【问题标题】:Aggregating columns matching two criteria聚合符合两个条件的列
【发布时间】:2015-02-05 15:04:54
【问题描述】:

我已经使用了 aggregate() 函数,但总是使用 FUN=mean 而不是 sum。它似乎有一些使事情变得困难的特质。

我正在使用世界卫生组织的死亡率数据集,其格式如下:

> head(data)
  Country Admin1 SubDiv Year List Cause Sex Frmat IM_Frmat Deaths1 Deaths2 Deaths3 Deaths4 Deaths5 Deaths6 Deaths7 Deaths8 Deaths9 Deaths10 Deaths11 Deaths12 Deaths13 Deaths14 Deaths15 Deaths16 Deaths17
1    1125     NA        2000  103   V72   1     2        8       1       0       0      NA      NA      NA       0       0       0        0        0        0        1        0        0        0        0
2    1125     NA        2000  103   V77   1     2        8       1       0       0      NA      NA      NA       0       0       0        0        0        1        0        0        0        0        0
3    1125     NA        2000  103   V78   1     2        8      19       1       0      NA      NA      NA       0       2       2        0        2        2        1        3        1        1        2
4    1125     NA        2000  103   V58   1     2        8      30       0       1      NA      NA      NA       1       2       2        1        4        3        2        4        5        1        0
5    1125     NA        2000  103   V58   2     2        8       4       0       0      NA      NA      NA       1       0       0        0        0        2        1        0        0        0        0
6    1125     NA        2000  103   V74   1     2        8       5       0       0      NA      NA      NA       1       1       0        0        1        0        1        0        1        0        0
  Deaths18 Deaths19 Deaths20 Deaths21 Deaths22 Deaths23 Deaths24 Deaths25 Deaths26 IM_Deaths1 IM_Deaths2 IM_Deaths3 IM_Deaths4  Name
1        0        0        0        0        0        0       NA       NA        0          0         NA         NA         NA Egypt
2        0        0        0        0        0        0       NA       NA        0          0         NA         NA         NA Egypt
3        0        1        0        0        0        1       NA       NA        0          1         NA         NA         NA Egypt
4        2        1        1        0        0        0       NA       NA        0          0         NA         NA         NA Egypt
5        0        0        0        0        0        0       NA       NA        0          0         NA         NA         NA Egypt
6        0        0        0        0        0        0       NA       NA        0          0         NA         NA         NA Egypt

这显示了 1 个国家(1125 == 埃及)在 1 年内,男性(Sex=1)和女性(Sex=2)的多种疾病(V72、V77 等)的原因。死亡数列是每个年龄组的死亡人数。

问题是我想按国家、每年、按性别对几个疾病代码的死亡人数进行分组。具体来说,我想要疾病代码 I20* - I25*。这些对应于缺血性心脏病死亡。

我做的第一件事是只选择那些行:

codes = c("1067","I20","I21","I22","I23","I24","I25",paste("I",200:250,sep="")) #ICD-10 codes for IHD

data_ihd <- subset(data, Cause %in% codes)

然后我尝试使用aggregate 对与 Country、Year、Sex 匹配的行求和。 我不再关心疾病代码 - 这个数据集每个国家/年/性别组合的每个疾病代码都有 1 行 - 我想将所有疾病视为 1 并将死亡人数相加。

看来我应该可以做到:

> aggregate(data_ihd, by=list(data_ihd$Name,data_ihd$Year,data_ihd$Sex),FUN=sum)
Error in Summary.factor(3518L, na.rm = FALSE) : 
  ‘sum’ not meaningful for factors

但似乎不是。这很奇怪,因为如果我使用 FUN=mean 会很高兴。

我知道这是因为我有因子,但我不明白如何在不主动删除列的情况下丢失因子?

你有什么建议?

我很高兴使用 dplyr 或 tidyr 之类的软件包,但不确定它们会如何提供帮助...

编辑:我想我在这里也需要小心,我只对 Deaths* 列而不是 Country、Year 列求和!我不确定聚合是否确保它不会对您在 by= 中提供的列求和

编辑:我被要求提供更多关于我想要什么的信息。如果我们采用以下数据集:

> head(data)
  Country Admin1 SubDiv Year List Cause Sex Frmat IM_Frmat Deaths1 Deaths2 Deaths3 Deaths4 Deaths5 Deaths6 Deaths7 Deaths8 Deaths9 Deaths10 Deaths11 Deaths12 Deaths13 Deaths14 Deaths15 Deaths16 Deaths17
1    1000     NA        2000  103   1   1     2        8       1       0       0      NA      NA      NA       0       0       0        0        0        0        1        0        0        0        0
2    1000     NA        2000  103   1   2     2        8       1       0       0      NA      NA      NA       0       0       0        0        0        1        0        0        0        0        0
3    1000     NA        2000  103   2   1     2        8      19       1       0      NA      NA      NA       0       2       2        0        2        2        1        3        1        1        2
4    1000     NA        2000  103   2   2     2        8      30       0       1      NA      NA      NA       1       2       2        1        4        3        2        4        5        1        0
5    1000     NA        2001  103   1   1     2        8       4       0       0      NA      NA      NA       1       0       0        0        0        2        1        0        0        0        0
6    1000     NA        2001  103   1   2     2        8       5       0       0      NA      NA      NA       1       1       0        0        1        0        1        0        1        0        0
7    1000     NA        2001  103   2   1     2        8       4       0       0      NA      NA      NA       1       0       0        0        0        2        1        0        0        0        0
8    1000     NA        2001  103   2   2     2        8       5       0       0      NA      NA      NA       1       1       0        0        1        0        1        0        1        0        0
9    2000     NA        2000  103   1   1     2        8       4       0       0      NA      NA      NA       1       0       0        0        0        2        1        0        0        0        0
10   2000     NA        2000  103   1   2     2        8       5       0       0      NA      NA      NA       1       1       0        0        1        0        1        0        1        0        0

变成

  Country Admin1 SubDiv Year List Sex Frmat IM_Frmat Deaths1 Deaths2 Deaths3 Deaths4 Deaths5 Deaths6 Deaths7 Deaths8 Deaths9 Deaths10 Deaths11 Deaths12 Deaths13 Deaths14 Deaths15 Deaths16 Deaths17
1    1000     NA        2000  103   1     2        8      20       1       0      NA      NA      NA       0       2       2        0        2        2        3        3        1        1        2
2    1000     NA        2000  103   2     2        8      31       0       1      NA      NA      NA       1       2       2        1        4        4        2        4        5        1        0
...
.    2000     NA        2000 ...

如您所见,第 1 行和第 3 行已为 Deaths 列求和,因为 Country、Year 和 Sex 相等。原因被忽略。当然,匹配的列还没有求和。

编辑 3:让我们简单化一下,然后:

  Country Year   Sex Cause  Deaths1 Deaths2 Deaths3
1    UK    2000   1    A    1       1       1
2    UK    2000   2    A    1       1       1
3    UK    2000   1    B    1       1       1
4    UK    2000   2    B    1       1       1
5    UK    2001   1    A    1       1       1
6    UK    2001   2    A    1       1       1
7    UK    2001   1    B    1       1       1
8    UK    2001   2    B    1       1       1
1    USA   2000   1    A    1       1       1
2    USA   2000   2    A    1       1       1
3    USA   2000   1    B    1       1       1
4    USA   2000   2    B    1       1       1
5    USA   2001   1    A    1       1       1
6    USA   2001   2    A    1       1       1
7    USA   2001   1    B    1       1       1
8    USA   2001   2    B    1       1       1
...

将所有原因组合在一起(总和),当县、年和性别相同时,变为:

  Country Year   Sex Deaths1 Deaths2 Deaths3 
1    UK    2000   1    2       2       2
2    UK    2000   2    2       2       2
3    UK    2001   1    2       2       2
4    UK    2001   2    2       2       2
5    USA   2000   1    2       2       2
6    USA   2000   2    2       2       2
7    USA   2001   1    2       2       2
8    USA   2001   2    2       2       2

我似乎不能在这里使用聚合,因为 1) 国家是一个因素; 2)它将总结年份

【问题讨论】:

  • 看看 dplyr 包和 select、filter 和 summarise 函数,我不太明白你到底想要什么,而且一个可重复的例子会有所帮助,
  • @James 不清楚您要获得哪些列的总和。如果你想得到Deathsaggregate(.~Name+Year+Sex, df[-c(1:3,5:6, 8:9)], FUN=sum, na.rm=TRUE, na.action=na.pass)的总和
  • 我已经添加了一个更好的说明我的意思,抱歉我不够清楚。

标签: r


【解决方案1】:

编辑:鉴于您在上面所说的,这应该可以帮助您:

好的,所以您想知道每个国家、每年和他们的性别有多少人死亡,忽略死因:

require(dplyr, magrittr)

group_by(data, Country, Year, Sex) %>% # here you specify which variable you wanna group by
summarise("deathsum.I20" = sum(I20), #now the sum gets calculated for each # level of the grouping variable
"deathsum.1" = sum(Deaths1),
    "deathsum.2" = sum(Deaths2),
    "deathsum.3" = sum(Deaths3),
    "deathsum.4" = sum(Deaths4)))

同样的逻辑适用于其余的死亡类别,这忽略了原因,这就是你想要的,

如果您还想忽略年龄并仅将所有死亡组相加,您可以在运行上述代码的其余部分之前执行此操作:

mutate(data, deathsum = rowsum(select(data, Deaths1:Deaths25))

这会在数据框数据中为您提供一个名为 deathsum 的新变量,它只是将不同年龄的所有死亡人数相加

【讨论】:

  • 对不起,不,我显然不清楚。我现在不关心疾病代码(我已经使用subset() 选择了我想要的所有疾病代码,现在我只想总结每一列的所有死亡人数,无论原因如何,但对于某个国家/年/性别。我已经编辑了我的问题以更好地反映这一点。
  • sry 我还是不明白你到底想要什么,给我一些示例输入数据,以及输出应该是什么样子,你是否希望数据按国家、年份和性别分组,然后为每个忽略年龄的人总结每行的死亡人数???
  • 我已经添加了一个更好的说明我的意思,抱歉我不够清楚。
  • 谢谢!我可以做这样的事情来快速总结所有 26 列吗?我觉得它应该可以工作,但它说意外的'=':group_by(data_ihd, Country, Year, Sex) %&gt;% summarise(paste("DeathSum",1:26,sep="") = sum(Deaths1:Deaths26))
  • 快速总结每个死亡列,你可以这样做select(data, country,year,sex, deaths1:deaths26) %&gt;% group_by(ihd, Country, Year, Sex) %&gt;% summarise_each(funs(sum))
猜你喜欢
  • 2017-08-24
  • 1970-01-01
  • 2018-11-30
  • 2015-08-17
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 2017-06-14
相关资源
最近更新 更多