使用dplyr分组后,能否在单管道步骤中实现组内基线值减法?
在dplyr单个管道中实现组内值减去指定基线值
当然可以在单个管道步骤里完成这个操作!而且有几种不同的方式,对应你需要的不同基线场景:
1. 减去组内第一个/第二个值
如果你的基线是组内的第n个值(比如第一个、第二个),直接用索引或者dplyr的first()/nth()函数就能实现:
减去组内第一个值
test %>% group_by(two) %>% mutate(new = three - first(three))
也可以直接用索引写法,效果完全一致:
test %>% group_by(two) %>% mutate(new = three - three[1])
减去组内第二个值
用nth()函数指定位置,或者直接用索引three[2]:
test %>% group_by(two) %>% mutate(new = three - nth(three, 2))
2. 减去指定条件的基线值(比如你的示例中one=="d"的对应值)
你的思路本身是对的,但有个小细节需要修正:在分组后的mutate操作里,不需要用.$one来引用列名,因为此时的代码是在每个分组的独立环境中运行的,直接写one就可以了:
test %>% group_by(two) %>% mutate(new = three - three[one == "d"])
⚠️ 注意:每个分组里one == "d"的匹配结果必须是唯一的一个值,否则会返回多个值导致报错。如果你的数据里每个分组可能存在多个匹配项,建议加上first()或者last()来明确取哪一个,比如:
test %>% group_by(two) %>% mutate(new = three - first(three[one == "d"]))
验证你的期望输出
用修正后的代码运行你的测试数据:
test <- tibble(one=c("c","d","e","c","d","e"), two=c("a","a","a","b","b","b"), three=1:6) test %>% group_by(two) %>% mutate(new = three - three[one == "d"])
会得到你想要的结果:
# A tibble: 6 x 4 # Groups: two [2] one two three new <chr> <chr> <int> <int> 1 c a 1 -1 2 d a 2 0 3 e a 3 1 4 c b 4 -1 5 d b 5 0 6 e b 6 1
整个操作完全在一个管道内完成,完美匹配你的需求~
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

