我目前在R中的data.table中使用以下数据集:
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 。
理想情况下,当我完成以下步骤时,数据集将如下所示:
id age_start age_end cases
1 2 4 1800
2 2 4 8300任何关于如何在data.table中实现这一点的建议都将受到极大的赞赏!
发布于 2020-02-03 21:15:07
您可以对第一个项目使用equi连接;对于第二个项目可以使用非equi连接:
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的答案),尽管我认为这会降低效率。
发布于 2020-02-03 20:31:32
我们可以使用逻辑条件指定i,分组by 'id',得到'cases‘的sum,同时添加'age_start','age_end’为2和4
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数据
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))https://stackoverflow.com/questions/60046671
复制相似问题