Выбрать столбец в соответствии со значением другого столбца в R

Я работаю над набором данных (а именно w3) в R, который выглядит следующим образом:

Q1   Q2   Q3   Q4 WorksheetID UserID
395 2178 2699 1494           3     65
395 2178 2694 1394           3     78
395 1178 2699 1394           3     79
395  278 2699 1394           3     80
295 1188 2799 1494           3     81
395 2278 2699 2394           3     81
395 2178 2699 1394           3     83
495 1178 2709 1394           3     84
395 2198 2799 1294           3     85
395 2178 2699 1394           3     85
395 1178 2699 1394           3     86

Каждый пользователь ответил на 4 вопроса (Q1,Q2,Q3,Q4) рабочего листа.

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

например, для Q1

Q1   freq UserID
295  1    81
395  9    65 78 79 80 81 83 85 85 86
495  1    84

Что я сделал, так это

w3Q1<-count(W3,"Q1")
for(i in w3Q1$Q1)
  {qry<-paste('select userID from w3 where Q1=',i)
  print(i)
  print(sqldf(qry))}

У меня вопрос, как мне объединить приведенные выше результаты и превратить его в таблицу с переменными Q1, freq, UserID (как показано выше)? Или есть какой-то более простой способ?

большое спасибо

2 ответа

Решение

Мы можем сначала подсчитать частоты с table и заставить его data.frame, Тогда мы можем сгруппировать и paste UserID с aggregate а также merge два кадра данных:

tbl <- as.data.frame(table(df$Q1))
ids <- aggregate(UserID~Q1, df, paste, collapse=' ')
merge(tbl, ids, by.x='Var1', by.y='Q1')
#   Var1 Freq                     UserID
# 1  295    1                         81
# 2  395    9 65 78 79 80 81 83 85 85 86
# 3  495    1                         84

Мы также можем сгруппировать по "Q1" и summarise с помощью dplyr,

library(dplyr)
df1 %>%
   group_by(Q1) %>%
   summarise(freq= n(), UserID= toString(UserID))
#     Q1  freq                             UserID
#   (int) (int)                              (chr)
#1   295     1                                 81
#2   395     9 65, 78, 79, 80, 81, 83, 85, 85, 86
#3   495     1                                 84

Для вопросов Q1:Q4 может быть лучше изменить форму на длинный gather от tidyr,

library(tidyr)
gather(df1, Var, Qs, Q1:Q4) %>% 
        group_by(Var, Qs) %>%
        summarise(freq=n(), UserID = toString(UserID))

Как упомянул @Steven Beaupré, если нам нужно list мы можем заменить toString с list(UserID)


Аналогичный подход с использованием data.table будет преобразовать "data.frame" в "data.table" (setDT(df1)), сгруппированные по 'Q1', получаем nrow (.N) как 'freq' и paste вместе "UserID"

library(data.table)
setDT(df1)[, list(freq=.N, UserID=toString(UserID)), by = Q1]

Для нескольких столбцов Q мы melt в "длинный" формат, а затем суммировать по группам.

melt(setDT(df1), measure=1:4)[, list(freq=.N, 
      UserID= toString(UserID)) ,.(variable, value)]
Другие вопросы по тегам