I am struggling with some scoping issues where I am trying to extract dataframe.
Here is a portion of a larger custom function to extract data from McNemar's test and other htest
objects:
get_data <- function(x, ...) {
data_name <- unlist(strsplit(x$data.name, " (and|by) "))
data_call <- lapply(data_name, str2lang)
columns <- lapply(data_call, eval)
as.table(columns[[1]])
}
The function works as expected:
# data
Performance <-
matrix(c(794, 86, 150, 570),
nrow = 2,
dimnames = list(
"1st Survey" = c("Approve", "Disapprove"),
"2nd Survey" = c("Approve", "Disapprove")
)
)
# using the function
mod <- stats::mcnemar.test(Performance)
get_data(mod) # it works!
#> 2nd Survey
#> 1st Survey Approve Disapprove
#> Approve 794 150
#> Disapprove 86 570
Doesn't work unfortunately
foo <- function(data) {
mod <- stats::mcnemar.test(data)
print(mod) # making sure data is being read internally
get_data(mod) # it doesn't work :(
}
foo(Performance)
#>
#> McNemar's Chi-squared test with continuity correction
#>
#> data: data
#> McNemar's chi-squared = 16.818, df = 1, p-value = 4.115e-05
#> Error in as.table.default(columns[[1]]): cannot coerce to a table
Is there any way to make this work, either by changing the custom function to extract data (get_data
) or by modifying the function where it is called (foo
)?
As @RuiBarradas mentioned in the comments, the mcnemar.test
is creating the list
element 'data.name' as the input data
instead of the value stored in it. It can be changed after applying the test
get_data <- function(x, ...) {
data_name <- unlist(strsplit(x$data.name, " (and|by) "))
data_call <- lapply(data_name, str2lang)
columns <- lapply(data_call, eval)
as.table(columns[[1]])
}
foo <- function(data) {
mod <- stats::mcnemar.test(data)
mod$data.name <- deparse(substitute(data))
print(mod) # making sure data is being read internally
get_data(mod) # it doesn't work :(
}
foo(Performance)
# McNemar's Chi-squared test with continuity correction
#data: Performance
#McNemar's chi-squared = 16.818, df = 1, p-value = 4.115e-05
# 2nd Survey
#1st Survey Approve Disapprove
# Approve 794 150
# Disapprove 86 570
Or use get
get_data <- function(x, ...) {
data_name <- unlist(strsplit(x$data.name, " (and|by) "))
as.table(get(data_name, envir = parent.frame()))
}
foo(Performance)
#McNemar's Chi-squared test with continuity correction
#data: Performance
#McNemar's chi-squared = 16.818, df = 1, p-value = 4.115e-05
# 2nd Survey
#1st Survey Approve Disapprove
# Approve 794 150
# Disapprove 86 570