Вычисление положительного ответа для набора данных опроса с использованием dplyr

У меня есть большой набор данных опроса, который выглядит следующим образом:

          trust09 q16a q16b q16c q16f q16g q23e
1         5A3    3    3    3    4    3    3
2         5A3    2    2    2    2    3    2
3         5A3    4    4    4    5    5    5
4         5A3    3    3    2    4    4    3
5         5A3   NA   NA   NA   NA   NA   NA
6         5A3    4    4    4    4    4    3
....
....
159524     TAN    2    2    3    4    4    3
159525     TAN    4    3    2    1    3    3
159526     TAN    4    4    4    4    4    4
159527     TAN    4   NA    4    2    3    4
159528     TAN    4    4    4    4    4    4
159529     TAN    4    4    4    5    4    5

trust09 - это код для больницы или организации, а остальные столбцы представляют собой вопросы опроса, которые категорически не согласны с полным согласием и оцениваются от 1 до 5 соответственно.

Каждый ряд соответствует ответу респондента, принадлежащего к какой-либо больнице.

Исходя из этих данных, я хочу вычислить частоту положительных ответов или PRR для каждого вопроса опроса для каждой больницы, то есть количество респондентов, которые ответили "согласен" (4) или "полностью согласен" (5) и выразить это в процентах по общему номеру респондентов.

Я могу получить общее нет. респондентов довольно легко из следующего кода:

df0 <- nss08 %>% select(trust09, q16a, q16b, q16c, q16f, q16g, q23e) %>% 
    group_by(trust09) %>%
    summarise_all(funs(length(.)))

Что дает мне следующую таблицу:

  trust09  q16a  q16b  q16c  q16f  q16g  q23e
<chr> <int> <int> <int> <int> <int> <int>
1     5A3   414   414   414   414   414   414
2     5A4   298   298   298   298   298   298
3     5A5   271   271   271   271   271   271
4     5A7   384   384   384   384   384   384
5     5A8   343   343   343   343   343   343
6     5A9   502   502   502   502   502   502

Я могу легко посчитать количество ответов для "Согласен" (4) и "Совершенно согласен" (5) для одного вопроса опроса, используя следующий код:

df1 <- nss08 %>%
  select(trust09, q16a) %>%
  group_by(trust09) %>%
  filter(q16a == 4|q16a == 5) %>%
  summarise_all(funs(length(.)))

который дает этот пример данных:

  trust09  q16a
<chr> <int>
1     5A3   124
2     5A4    65
3     5A5   107
4     5A7   142
5     5A8   126
6     5A9   159
....

Я также получаю тот же результат, используя:

aggregate(q16a ~ trust09, data = nss08[nss08$q16a == 4|nss08$q16a == 5, ], length)

Затем я просто объединяю эти две данные и вычисляю PRR для переменной / вопроса q16a, т.е. нет. респондентов, которые ответили "Согласен" (4) или "Совершенно согласен" (5) на этот вопрос, делят дивиденды на общее количество ответов на вопрос и затем умножают на 100.

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

Я пробовал следующее, но я получаю сообщение об ошибке:

myList <- vector("list", length = length(myVars))

for (x in seq_along(myVars)){
myList[x] <- aggregate(myVars[x] ~ trust09, data = nss08[nss08$myVars[,x] == 4|nss08$myVars[,x] == 5, ], length)}

Я также попробовал это без какого-либо успеха:

for (x in seq_along(myVars)){
 myList[[x]] <- nss08 %>%
select(trust09, myVars[x]) %>%
group_by(trust09) %>%
filter(myVars[x] == 4|myVars[x] == 5) %>%
summarise(length(myVars[x]))
}

Может быть, вы можете увидеть из кода, что я пытаюсь сделать здесь.

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

Спасибо.

2 ответа

Решение

Предположим, что ваш фрейм данных содержит trust09 и все остальные столбцы соответствуют вопросам, которые вы хотите обобщить, вы можете использовать summarize_all и посчитать количество 4 а также 5 ответы с sum(col %in% 4:5, na.rm=TRUE) и разделить его на length(col) непосредственно:

df %>% group_by(trust09) %>% summarise_all(~ sum(. %in% 4:5, na.rm = T)/length(.))
# here . refers to all other columns individually except the group variable

# A tibble: 2 x 7
#  trust09      q16a      q16b      q16c      q16f      q16g      q23e
#   <fctr>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
#1     5A3 0.3333333 0.3333333 0.3333333 0.6666667 0.5000000 0.1666667
#2     TAN 0.8333333 0.5000000 0.6666667 0.6666667 0.6666667 0.6666667

Данные используются следующим образом:

dput(df)
structure(list(trust09 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("5A3", "TAN"), class = "factor"), 
    q16a = c(3L, 2L, 4L, 3L, NA, 4L, 2L, 4L, 4L, 4L, 4L, 4L), 
    q16b = c(3L, 2L, 4L, 3L, NA, 4L, 2L, 3L, 4L, NA, 4L, 4L), 
    q16c = c(3L, 2L, 4L, 2L, NA, 4L, 3L, 2L, 4L, 4L, 4L, 4L), 
    q16f = c(4L, 2L, 5L, 4L, NA, 4L, 4L, 1L, 4L, 2L, 4L, 5L), 
    q16g = c(3L, 3L, 5L, 4L, NA, 4L, 4L, 3L, 4L, 3L, 4L, 4L), 
    q23e = c(3L, 2L, 5L, 3L, NA, 3L, 3L, 3L, 4L, 4L, 4L, 5L)), .Names = c("trust09", 
"q16a", "q16b", "q16c", "q16f", "q16g", "q23e"), class = "data.frame", row.names = c(NA, 
12L))

База на вашем dplyr код, я сделал эту функцию, вы можете вызвать ее в forloop или в пределах apply

xx=function(arg){
  var=quo(arg)
  #print(var)
  df1=df %>%
    select(trust09, !!!quos(arg)) %>%
    group_by(trust09) %>%
    filter_(.dots=paste0(arg,'==','4|',arg,'== 5'))%>%
    summarise(length(!!var))
  return(df1)
}



xx('q16a')

<quosure: frame>
~arg
# A tibble: 2 x 2
  trust09 `length(arg)`
    <chr>         <int>
1     5A3             1
2     TAN             1
Другие вопросы по тегам