修改
我留下这个问题,以防它对某人有帮助,但它似乎实际上是dplyr
版本的问题[见下文]。
在R
并使用dplyr
,我有两个数据框df1
和df2
:
library(dplyr)
set.seed(2)
df1 = data.frame(letter=rep(letters[1:2], each=5), min=runif(10))
df1 = mutate(df1, max=min+runif(10))
df2 = data.frame(letters=rep(letters[1:2], 25), position=runif(50), val=rnorm(50))
对于df1
的每一行,我想计算所有df2$val
的总和,df2$position
介于df1$min
和df1$max
之间df2$letters
}等于df1$letter
。
从this question on SO开始,我可以完成条件的第一部分(即df2$position
和df1$min
之间的df1$max
):
incompleteCond = df1 %>% rowwise %>%
mutate(sumval = sum( df2$val[between(df2$position, min, max)] ))
但这是对满足此条件的df2
行的求和,而不确保df2$letters
与相应的df1$letter
一致。如何在其他列中添加此条件?
以下尝试不起作用:
# Note: these solutions actually DO the job with dplyr_0.4.3!
wrong1 = df1 %>% rowwise %>%
mutate(sumval =
sum( df2$val[between(df2$position, min, max) & df2$letters==letter] ))
wrong3 = df1 %>% rowwise %>%
mutate(sumval =
sum( df2[(df2$position>=min) & (df2$position<=max) & (df2$letters==letter),
'val'] ))
修改
看起来这实际上是版本问题:从dplyr_0.4.1
转到dplyr_0.4.3
解决了问题,这意味着上面的wrong1
和wrong3
实际上都是正确的(他们只给出版本为0.4.1
的零...)
作为旁注,我还没有找到dplyr
- 只有子集(filter
)df2
的解决方案,但上面的工作方式,以及不错的回答@ r2evans。
答案 0 :(得分:1)
我认为你很接近:
df1 %>%
rowwise() %>%
mutate(sumval = sum( df2$val[df2$letters == letter & between(df2$position, min, max)] ))
## Source: local data frame [10 x 4]
## Groups: <by row>
## letter min max sumval
## (fctr) (dbl) (dbl) (dbl)
## 1 a 0.1848823 0.7375563 -3.8432366
## 2 a 0.7023740 0.9412688 -0.9138266
## 3 a 0.5733263 1.3338396 4.1341039
## 4 a 0.1680519 0.3488720 -2.5142686
## 5 a 0.9438393 1.3491215 3.6405305
## 6 b 0.9434750 1.7970234 -0.1416608
## 7 b 0.1291590 1.1055575 -5.2083130
## 8 b 0.8334488 1.0592743 1.0618699
## 9 b 0.4680185 0.9128277 -2.3595283
## 10 b 0.5499837 0.6249632 0.0000000
@aosmith建议的另一个选择是首先加入两个数据集。
df1 %>%
mutate(grp = 1:n()) %>%
left_join(df2, by=c('letter'='letters')) %>%
filter(position >= min & position <= max) %>%
group_by(grp) %>%
summarize(letter=letter[1], min=min[1], max=max[1], sumval=sum(val)) %>%
select(-grp)
## Source: local data frame [9 x 4]
## letter min max sumval
## (fctr) (dbl) (dbl) (dbl)
## 1 a 0.1848823 0.7375563 -3.8432366
## 2 a 0.7023740 0.9412688 -0.9138266
## 3 a 0.5733263 1.3338396 4.1341039
## 4 a 0.1680519 0.3488720 -2.5142686
## 5 a 0.9438393 1.3491215 3.6405305
## 6 b 0.9434750 1.7970234 -0.1416608
## 7 b 0.1291590 1.1055575 -5.2083130
## 8 b 0.8334488 1.0592743 1.0618699
## 9 b 0.4680185 0.9128277 -2.3595283
您可能会注意到的一个区别是,最后一个“b”组未包含在后一组中,因为没有数据在给定范围内。
编辑:我将连接代码从使用between
(不会将最小/最大参数向量化)更改为更简单的向量比较,从而否定了使用{{的性能惩罚1}}。我还删除了rowwise
,因为在ungroup
之后,无论如何都会删除分组。
供参考:
summarize