首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R data.table按组有条件地聚合行

R data.table按组有条件地聚合行
EN

Stack Overflow用户
提问于 2020-02-03 20:26:54
回答 2查看 63关注 0票数 1

我目前在R中的data.table中使用以下数据集:

代码语言:javascript
复制
    id   age_start   age_end    cases
    1    2           2          1000          
    1    3           3          500           
    1    4           4          300           
    1    2           4          1800            
    2    2           2          8000          
    2    3           3          200           
    2    4           4          100           

  • 在给定的数据集中,我只需要age_start == 2和age_end ==4的值。在每个ID中,age_start !=2和age_end !=4的情况下,我需要对行进行求和或聚合,以创建一个age_start==2和age_end ==4组。在这些情况下,我需要总结age_start==2& age_end==2、age_start==3和age_end==3的情况。除了age_start==4 & age_end==4到新的age_start==2和age_end==4行之外,在这些行之后的
  • 被总结为一行之后,我希望删除用于生成新的age_start==2和age_start==4行的行(即年龄值2-2、3-3和4-4),因为它们不再需要

理想情况下,当我完成以下步骤时,数据集将如下所示:

代码语言:javascript
复制
    id   age_start   age_end    cases
    1    2           4          1800          
    2    2           4          8300

任何关于如何在data.table中实现这一点的建议都将受到极大的赞赏!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-03 21:15:07

您可以对第一个项目使用equi连接;对于第二个项目可以使用非equi连接:

代码语言:javascript
复制
m_equi = x[.(id = unique(id), age_dn = 2, age_up = 4), 
  on=.(id, age_start = age_dn, age_end = age_up),
  nomatch=0
]

m_nonequi = x[!m_equi, on=.(id)][.(id = unique(id), age_dn = 2, age_up = 4), 
  on=.(id, age_start >= age_dn, age_end <= age_up), 
  .(cases = sum(cases)), by=.EACHI
]

res = rbind(m_equi, m_nonequi)

   id age_start age_end cases
1:  1         2       4  1800
2:  2         2       4  8300

它的工作原理:

  • x[i]使用i中的值来根据on=.
  • nomatch=0中指定的规则在x中查找行和列,这意味着在x[i]中删除了不匹配的i行,因此m_equi仅以id=1.
  • x[!m_equi, on=.(id)]结束,它是一个跳过id=1的反连接,因为为了执行aggregation.

,我们已经按照x[i]中的i的每一行在equi join.

  • by=.EACHI组中匹配了它。

另一种选择是在具有start 2和end 4的行上进行反连接,这样所有组都需要被聚合(类似于@akrun的答案),尽管我认为这会降低效率。

票数 3
EN

Stack Overflow用户

发布于 2020-02-03 20:31:32

我们可以使用逻辑条件指定i,分组by 'id',得到'cases‘的sum,同时添加'age_start','age_end’为2和4

代码语言:javascript
复制
library(data.table)
as.data.table(df1)[age_start != 2|age_end != 4, 
     .(age_start = 2, age_end = 4, cases = sum(cases)), id]
#  id age_start age_end cases
#1:  1         2       4  1800
#2:  2         2       4  8300

数据

代码语言:javascript
复制
df1 <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 2L), age_start = c(2L, 
3L, 4L, 2L, 2L, 3L, 4L), age_end = c(2L, 3L, 4L, 4L, 2L, 3L, 
4L), cases = c(1000L, 500L, 300L, 1800L, 8000L, 200L, 100L)), 
  class = "data.frame", row.names = c(NA, 
-7L))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60046671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档