【问题标题】:Assign value to a new column based on value in a second column grouped by a third column?根据由第三列分组的第二列中的值将值分配给新列?
【发布时间】:2020-01-12 05:42:53
【问题描述】:

我有类似以下的数据(姑且称之为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 以及介于mean+sdmean-sd 之间来标记“高”、“低”和“中” ?

【问题讨论】:

  • 在基础 R 中 ave 向原始数据添加一列,由 group 计算,例如 df$allMeans = with(df, ave(rating, participant, FUN = mean))。因此,您可以使用ave 作为平均值,再次使用 ave 作为 sd,然后进行计算。如今,大多数人更喜欢使用 dplyrdata.table 包进行分组操作,这样您就可以一次完成所有操作。

标签: r dataframe data-analysis data-cleaning


【解决方案1】:

我们可以group_byparticipant 并将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 的好处是可以很容易地添加具有多个输出的多个条件。


在base R中,我们可以使用ave

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

【讨论】:

  • 感谢您的解决方案。我能够做到,但是当我尝试将其转换为 3 级标签时也发现了一个错误:df &lt;- df %&gt;% group_by(participant) %&gt;% mutate(label = case_when(rating &gt;= (mean(rating, na.rm = TRUE) + sd(rating, na.rm = TRUE)/2) ~ "high", rating &lt;= (mean(rating, na.rm = TRUE) - sd(rating, na.rm = TRUE)/2) ~ "low"), TRUE ~ "medium") 它说 [错误:列 TRUE ~ “medium”` is of unsupported typequoted call`。任何想法为什么?
  • @FINNNNN 你只是在错误的地方有括号。试试df %&gt;% group_by(participant) %&gt;% mutate(label = case_when(rating &gt;= (mean(rating, na.rm = TRUE) + sd(rating, na.rm = TRUE)/2) ~ "high", rating &lt;= (mean(rating, na.rm = TRUE) - sd(rating, na.rm = TRUE)/2) ~ "low", TRUE ~ "medium"))
猜你喜欢
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
相关资源
最近更新 更多