Выбрать столбец в соответствии со значением другого столбца в 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)]