select 列根据 R 中另一列的值
select column according to value of another column in R
我正在 R 中处理一个如下所示的数据集(即 w3):
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 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))}
我的问题是,如何将上面的结果结合起来,变成table,变量为Q1、freq、UserID(如上图)?或者有什么更简单的方法吗?
非常感谢
我们可以先用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
我们还可以使用 dplyr
.
按 'Q1' 和 summarise
分组
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,最好将 tidyr
中的 gather
重新整形为长格式。
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
格式化为'long',然后分组汇总。
melt(setDT(df1), measure=1:4)[, list(freq=.N,
UserID= toString(UserID)) ,.(variable, value)]
我正在 R 中处理一个如下所示的数据集(即 w3):
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 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))}
我的问题是,如何将上面的结果结合起来,变成table,变量为Q1、freq、UserID(如上图)?或者有什么更简单的方法吗?
非常感谢
我们可以先用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
我们还可以使用 dplyr
.
summarise
分组
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,最好将 tidyr
中的 gather
重新整形为长格式。
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
格式化为'long',然后分组汇总。
melt(setDT(df1), measure=1:4)[, list(freq=.N,
UserID= toString(UserID)) ,.(variable, value)]