根据由第三列分组的第二列中的值将值分配给新列?

时间:2019-09-10 12:52:31

标签: r dataframe data-analysis data-cleaning

我的数据类似于以下内容(我们称其为df):

participant item    rating
1           I1      5
1           I2      6
1           I3      6
1           I4      6
1           I5      7
1           I6      6
1           I7      6
1           I8      5
2           I1      4
2           I2      4
2           I3      3
2           I4      2
2           I5      3
2           I6      1
2           I7      2
2           I8      4
3           I1      7
3           I2      6
3           I3      7
3           I4      6
3           I5      3
3           I6      3
3           I7      6
3           I8      4

一列代表参与者的编号,一列代表测试的项目(每个参与者相同),最后一列代表项目的评分。我想标记每个参与者的评分,以便将大于八个项目中一个参与者的所有评分平均值的个人评分标记为“高响应”,否则为“低响应”。

我认为可以创建另一列来简单显示每个参与者的评分平均值:

allMeans <- aggregate(df$rating, by=list(df$participant), FUN=mean, na.rm=TRUE)

然后复制均值向量以匹配行的长度:

df$rating.mean <- rep(allMeans$x, each = 8)

根据df$ratingsdf$allMeans每行之间的比较,最后将标签分配给新列。

但是我只是想知道是否有一些功能可以通过一行代码或更多“吸引人”的解决方案来实现?另外,如果现在标记的标准发生了变化,例如我们需要基于高于mean + sd,低于mean - sd以及介于{{1之间的情况下,对“高”,“低”和“中”进行标记}}和mean+sd

1 个答案:

答案 0 :(得分:4)

我们可以group_by participant并将ratingmean rating的组进行比较并分配标签。

library(dplyr)
df %>%
  group_by(participant) %>%
  mutate(label = case_when(rating > mean(rating, na.rm = TRUE) ~ "high response", 
                            TRUE ~ "low response"))


#   participant item  rating label        
#         <int> <fct>  <int> <chr>        
# 1           1 I1         5 low response 
# 2           1 I2         6 high response
# 3           1 I3         6 high response
# 4           1 I4         6 high response
# 5           1 I5         7 high response
# 6           1 I6         6 high response
# 7           1 I7         6 high response
# 8           1 I8         5 low response 
# 9           2 I1         4 high response
#10           2 I2         4 high response
# … with 14 more rows

使用case_when的好处是很容易添加具有多个输出的多个条件。


在基数R中,我们可以使用ave

df$label <- with(df, c("low response", "high response")
                     [(rating > ave(rating, participant)) + 1])