Как я могу написать функцию для создания нескольких таблиц из столбцов фрейма данных?

#r

#r

Вопрос:

Я хотел бы создать таблицы непредвиденных обстоятельств и запустить chisq.test() и т.д. для нескольких элементов в фрейме данных.

Различные попытки привели к «Ошибке в таблице (y $ x, y $ q2): все аргументы должны иметь одинаковую длину».

Я думаю, что приведенный ниже пример фокусируется на моей центральной проблеме, хотя в конечном итоге я бы написал более сложную функцию. Мне было бы интересно найти решения для моей конкретной функции или для моего общего подхода. Спасибо!

 my_df <- structure(list(q1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), 
                              .Label = c("Choice1", "Choice2"), 
                              class = "factor"), 
                        q2 = structure(c(1L, 1L, 4L, 5L, 4L, 1L, 1L, 4L), 
                              .Label = c("Agree", "Disagree","N/A or No Opinion", 
                                         "Strongly Agree", "Strongly Disagree"), 
                              class = "factor"),
                        q3 = structure(c(1L, 4L, 1L, 4L, 1L, 4L, 4L, 4L), 
                              .Label = c("Agree", "Disagree","N/A or No Opinion", 
                                    "Strongly Agree", "Strongly Disagree"), 
                              class = "factor")),
                   row.names = c(NA, -8L), 
                   class = c("tbl_df", "tbl", "data.frame"))

my_fn <- function(x, y) {
 table(y$x, y$`q2`)

}

my_fn(names(my_df)[1], my_df)
#Error in table(y$x, y$q2) : all arguments must have the same length

lapply(names(my_df), my_fn, my_df)
#Error in table(y$x, y$q2) : all arguments must have the same length
  

Ответ №1:

Попробуйте это. Проблема может быть связана с использованием $ для переменных. В случае, если вы хотите использовать имена, лучше использовать [[]] , чтобы строки для имен могли быть поняты функцией. Вот код с небольшими изменениями в вашей функции. Я добавил несколько примеров:

 #Function
my_fn <- function(x, y) {
  table(y[[x]], y[['q2']])
}
#Code
my_fn('q1', my_df)
lapply(names(my_df),my_fn,y=my_df)
  

Вывод:

 [[1]]
         
          Agree Disagree N/A or No Opinion Strongly Agree Strongly Disagree
  Choice1     4        0                 0              3                 1
  Choice2     0        0                 0              0                 0

[[2]]
                   
                    Agree Disagree N/A or No Opinion Strongly Agree Strongly Disagree
  Agree                 4        0                 0              0                 0
  Disagree              0        0                 0              0                 0
  N/A or No Opinion     0        0                 0              0                 0
  Strongly Agree        0        0                 0              3                 0
  Strongly Disagree     0        0                 0              0                 1

[[3]]
                   
                    Agree Disagree N/A or No Opinion Strongly Agree Strongly Disagree
  Agree                 1        0                 0              2                 0
  Disagree              0        0                 0              0                 0
  N/A or No Opinion     0        0                 0              0                 0
  Strongly Agree        3        0                 0              1                 1
  Strongly Disagree     0        0                 0              0                 0
  

Ответ №2:

Мы можем использовать count from dplyr . Он получит данные в формате tibble

 library(dplyr)
library(purrr)
my_fn <- function(data, col1) {data %>% 
          count(!! rlang::sym(col1), q2)}
map(names(my_df), ~ my_fn(my_df, .x))
#[[1]]
# A tibble: 3 x 3
#  q1      q2                    n
#  <fct>   <fct>             <int>
#1 Choice1 Agree                 4
#2 Choice1 Strongly Agree        3
#3 Choice1 Strongly Disagree     1

#[[2]]
# A tibble: 3 x 2
#  q2                    n
#  <fct>             <int>
#1 Agree                 4
#2 Strongly Agree        3
#3 Strongly Disagree     1

#[[3]]
# A tibble: 5 x 3
#  q3             q2                    n
#  <fct>          <fct>             <int>
#1 Agree          Agree                 1
#2 Agree          Strongly Agree        2
#3 Strongly Agree Agree                 3
#4 Strongly Agree Strongly Agree        1
#5 Strongly Agree Strongly Disagree     1
  

Комментарии:

1. Спасибо — это решает часть проблемы. Я не уверен, что смогу передать результат в качестве аргумента для chisq.test() или rcompanion::cramerV(), хотя