1

I'm trying to create a function that contains the table() function, but I keep returning the error "Error in table(df$var, df$arm) : all arguments must have the same length ". I've played around with every alternative option to referencing the columns that I can think of but to no avail.

Here is a reproduceable example:

x <- c(0, 1, 0, 1)
arm <- c("A", "A", "B", "B")
study.df <- data.frame(x, arm, row.names = NULL)


f.table <- function(df, var) {
  p <- table(df$var, df$arm) %>%
    fisher.test(alternative = "two.sided") %>%
    .$p.value
  return(p)
}

f.table(study.df, x)
wwa2199
  • 13
  • 2
  • 2
    `study.df` doesn't have a column named `var`. – Martin Gal Aug 29 '21 at 20:59
  • probably a duplicate of https://stackoverflow.com/questions/12389318/dollar-sign-before-a-variable and https://stackoverflow.com/questions/18222286/dynamically-select-data-frame-columns-using-and-a-character-value – user20650 Aug 29 '21 at 21:01
  • Adding to @user20650's mention of dupes, this is also mixing non-standard evaluation (NSE) since you use `x` expecting the function to use `df$x`, which it will not do without deliberate effort. – r2evans Aug 29 '21 at 21:11

2 Answers2

2

As we are passing unquoted argument, use deparse/substitute and instead of $ use [[ for extraction

f.table <- function(df, var) {
   p <- table(df[[deparse(substitute(var))]], df$arm) %>%
     fisher.test(alternative = "two.sided") %>%
     .$p.value
   return(p)
 }

-testing

> f.table(study.df, x)
[1] 1

which is the same value we get outside the function

> table(study.df$x, study.df$arm) %>% fisher.test(alternative = "two.sided") %>%
+     .$p.value
[1] 1
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Wow worked like a charm, thank you so much!! I never would have gotten there and I really appreciate your help. – wwa2199 Aug 29 '21 at 21:25
2

You need to change how you call the argument var inside the function, here is a solution:

 f.table <- function(df, var) {
  p <-
    table(df[,var], df$arm) %>%
    fisher.test(alternative = "two.sided") %>%
    .$p.value
  return(p)
}

f.table(study.df, "x")
Vinícius Félix
  • 8,448
  • 6
  • 16
  • 32