Передача таблиц в матрицу списков с использованием двойного цикла for - PullRequest
2 голосов
/ 13 июля 2020

Я посмотрел на SO (например, здесь ), но еще не нашел что-то, что делает то, что мне нужно.

Я учусь программировать в новом dplyr v1.0.0, и я пытается найти способ передать результаты функции, которая возвращает список из двух элементов, один из которых является строкой, а другой - таблицей, в двухмерный список.

Вот набор данных игрушки с тремя бинарными переменными результата и пятью предикторами, два из которых являются факторами.

set.seed(1)
library(dplyr)
df <- tibble(outcome1 = factor(rbinom(10,1, prob = 0.5), levels = 0:1, labels = c("unmet", "met")),
             outcome2 = factor(rbinom(10,1, prob = 0.2), levels = 0:1, labels = c("unmet", "met")),
             outcome3 = factor(rbinom(10,1, prob = 0.8), levels = 0:1, labels = c("unmet", "met")),
             pred1 = rnorm(10),
             pred2 = rnorm(10,5,1),
             pred3 = rnorm(10,15,3),
             pred4 = factor(rep(letters[1:2],5)),
             pred5 = factor(rep(letters[3:4],each=5)))

Теперь предположим, что я хочу вернуть долю неудовлетворенных и выполненных в каждой из трех переменных результата для каждого из двух факторных предикторов .

Я могу написать функцию dplyr, которая будет возвращать таблицу неудовлетворенных и встреченных для указанной переменной результата для указанного предиктора

catFunct_grouped <- function(d, group_var, out_var) {
  d %>% 
    group_by(.data[[group_var]], .data[[out_var]]) %>%
      summarise(count = n()) %>%
        mutate(tot = sum(count),
               perc = round(100*count/tot,2))
}

df %>% catFunct_grouped("pred4", "outcome1")

#output
#   pred4 outcome1 count   tot  perc
#   <fct> <fct>    <int> <int> <dbl>
# 1 a     unmet        2     5    40
# 2 a     met          3     5    60
# 3 b     unmet        2     5    40
# 4 b     met          3     5    60

Но скажем, теперь я хочу получить все 2 x 3 = 6 попарных комбинаций двух факторных предикторов и трех бинарных исходов?

Я попытался создать двойное for-l oop, передав шесть парных комбинаций (вместе с дополнительным элементом перечисление рассматриваемой переменной результата) в мою функцию, а затем в пустой список.

outNames <- paste0("outcome", 1:3)
predNames <- paste0("pred", 4:5)

grFact <- list()
for (r in 1:length(outNames)) {
  for (c in 1:length(predNames)) {
    grFact[[r]] <- list(outVariable = outNames[r], # prints the outcome name
                        outDF = list(df %>% catFunct_grouped(predNames[c], outNames[r])))
  }
}

Но когда я вызываю новый список ...

grFact

... Я получите следующий результат

# [[1]]
# [[1]]$outVariable
# [1] "outcome1"
# 
# [[1]]$outDF
# [[1]]$outDF[[1]]
# # A tibble: 4 x 5
# # Groups:   pred5 [2]
#   pred5 outcome1 count   tot  perc
#   <fct> <fct>    <int> <int> <dbl>
# 1 c     unmet        3     5    60
# 2 c     met          2     5    40
# 3 d     unmet        1     5    20
# 4 d     met          4     5    80
# 
# 
# 
# [[2]]
# [[2]]$outVariable
# [1] "outcome2"
# 
# [[2]]$outDF
# [[2]]$outDF[[1]]
# # A tibble: 3 x 5
# # Groups:   pred5 [2]
#   pred5 outcome2 count   tot  perc
# <fct> <fct>    <int> <int> <dbl>
# 1 c     unmet        5     5   100
# 2 d     unmet        4     5    80
# 3 d     met          1     5    20
# 
# 
# 
# [[3]]
# [[3]]$outVariable
# [1] "outcome3"
# 
# [[3]]$outDF
# [[3]]$outDF[[1]]
# # A tibble: 4 x 5
# # Groups:   pred5 [2]
#   pred5 outcome3 count   tot  perc
# <fct> <fct>    <int> <int> <dbl>
# 1 c     unmet        1     5    20
# 2 c     met          4     5    80
# 3 d     unmet        1     5    20
# 4 d     met          4     5    80

..., который находится на правильном пути, но показывает соотношение выполненных и неудовлетворенных для каждого из трех исходов для только второго предиктора .

Я предполагаю, что мне нужна матрица или массив списков для передачи таблиц, но я не уверен в синтаксисе для этого с for-l oop.

Любая помощь очень ценится.

1 Ответ

2 голосов
/ 13 июля 2020

Поскольку r идет от 1:length(outNames), поэтому grFact сохраняет только список длиной 3. Попробуйте вместо этого использовать вложенные lapply / map.

unlist(lapply(outNames, function(x) lapply(predNames, function(y) 
       list(outVariable = x, outDF = df %>% catFunct_grouped(x, y)))),
        recursive = FALSE)


#[[1]]
#[[1]]$outVariable
#[1] "outcome1"

#[[1]]$outDF
# A tibble: 4 x 5
# Groups:   outcome1 [2]
#  outcome1 pred4 count   tot  perc
#  <fct>    <fct> <int> <int> <dbl>
#1 unmet    a         2     4    50
#2 unmet    b         2     4    50
#3 met      a         3     6    50
#4 met      b         3     6    50

#[[2]]
#[[2]]$outVariable
#[1] "outcome1"

#[[2]]$outDF
# A tibble: 4 x 5
# Groups:   outcome1 [2]
#  outcome1 pred5 count   tot  perc
#  <fct>    <fct> <int> <int> <dbl>
#1 unmet    c         3     4  75  
#2 unmet    d         1     4  25  
#3 met      c         2     6  33.3
#4 met      d         4     6  66.7
#...
#...
...