【问题标题】:Summarize data by group and column name按组和列名汇总数据
【发布时间】:2019-09-17 05:08:05
【问题描述】:

我有以下数据框

library(tidyverse)    
ID <- c('A','A','B','C','D','E','F')
Level1 <- c(20,50,30,10,15,10,NA)
Level2 <- c(40,33,84,NA,20,1,NA)
Level3 <- c(60,40,60,10,25,NA,NA)
Grade1 <- c(20,50,30,10,15,10,NA)
Grade2 <- c(40,33,84,NA,20,1,NA)

DF <- data.frame(ID,Level1,Level2,Level3,Grade1,Grade2)
  ID Level1 Level2 Level3 Grade1 Grade2
1  A     20     40     60     20     40
2  A     50     33     40     50     33
3  B     30     84     60     30     84
4  C     10     NA     10     10     NA
5  D     15     20     25     15     20
6  E     10      1     NA     10      1
7  F     NA     NA     NA     NA     NA

我的目标是按 ID 对数据进行分组,通过计算平均值来汇总列名包含字符串“级别”的列。理想情况下,输出应该是这样的

ID        mean (Level1+Level2+Level3)
A         40.5
B         58
C         10
....

这是我的代码

DF %>%
  group_by(ID) %>%
  select(starts_with('Level')) %>%
  summarise(mean(.,na.rm = TRUE))

当我运行代码时,我得到以下输出

Adding missing grouping variables: `ID`
# A tibble: 6 x 2
  ID    `mean(., na.rm = TRUE)`
  <fct>                   <dbl>
1 A                          NA
2 B                          NA
3 C                          NA
4 D                          NA
5 E                          NA
6 F                          NA
Warning messages:
1: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA
2: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA
3: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA
4: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA
5: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA
6: In mean.default(., na.rm = TRUE) :
  argument is not numeric or logical: returning NA

云请帮我理解我的代码有什么问题。对于建议的解决方案 1) 应通过使用 dplyr 中的starts_with() 或 contains() 等函数将列名与字符串匹配来选择列。 2)如果可能的话,我还想避免旋转或收集功能。

感谢您的帮助

【问题讨论】:

标签: r dplyr tidyverse


【解决方案1】:

Eidt:更新了跨“级别”列聚合的答案。

DF %>%
  gather(col, value, -ID) %>%
  filter(col %>% str_starts("Level")) %>%
  group_by(ID) %>%
  summarise(mean = mean(value, na.rm = TRUE))

## A tibble: 6 x 2
#  ID     mean
#  <fct> <dbl>
#1 A      40.5
#2 B      58  
#3 C      10  
#4 D      20  
#5 E       5.5
#6 F     NaN  

原始答案 这是 Sang won kim 所写内容的变体,适用于我的 dplyr 0.8.3,即当前的 CRAN 版本。

DF %>%
  group_by(ID)  %>%
  summarise_at(vars(starts_with('Level')), mean, na.rm = TRUE)

# A tibble: 6 x 4
  ID    Level1 Level2 Level3
  <fct>  <dbl>  <dbl>  <dbl>
1 A         35   36.5     50
2 B         30   84       60
3 C         10  NaN       10
4 D         15   20       25
5 E         10    1      NaN
6 F        NaN  NaN      NaN

【讨论】:

  • 嗨,乔恩,我希望将 3 列合并并分开计算。请在我发布的问题中查看我想要的结果。
  • 谢谢乔恩。有没有不将数据帧转换成长格式的解决方案?
  • 运行修改后的代码时,我收到以下错误消息:错误:评估错误:找不到函数“str_starts”。
  • str_starts 来自 stringr,它应该像 OP 中一样加载 library(tidyverse)tidyverse.org/packages
  • 我已经导入了 tidyverse 和 stringr,但仍然收到错误消息。
【解决方案2】:
DF %>%
  group_by(ID) %>%
  select(starts_with('Level')) %>%
  summarise_all(funs(mean(.,na.rm = TRUE)))

DF %>%
  group_by(ID) %>%
  select(starts_with('Level')) %>%
  summarise_all(list(~mean(.,na.rm = TRUE)))

你可以得到这个:

  ID    Level1 Level2 Level3
  <fct>  <dbl>  <dbl>  <dbl>
1 A         35   36.5     50
2 B         30   84       60
3 C         10  NaN       10
4 D         15   20       25
5 E         10    1      NaN
6 F        NaN  NaN      NaN

【讨论】:

  • @Jon Spring 不工作 summarise_all(list(~mean(.,na.rm = TRUE)))?
  • 这似乎与过去发生的错误相似。我会再找一点。对不起。 (github.com/tidyverse/dplyr/issues/643)
  • 啊哈!我从先前的问题中加载了raster 包,在问题中指出是一个问题。重新启动修复它。谢谢!
  • @Sangwonkim 我需要聚合而不是分开的方法。请参考我编辑的问题。
猜你喜欢
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多