使用tidyverse按组交替替换列中满足条件的值
tidyverse按组交替替换列中满足条件的值
嘿,我来帮你搞定这个按组交替替换的问题!你的思路方向是对的,但之前的代码在生成交替序列的时候用错了rep的参数,导致没达到预期效果。
首先先确认你的原始数据(我稍微修正了一下A列的生成代码,确保它能正确重复成8行):
library(tidyverse) # 原始数据 df <- data.frame( group = rep(letters[1:2], each = 4), A = rep(letters[3:4], 4), B = letters[1:8] )
要实现按组、当A == "c"时交替用"x"和"y"替换B列的需求,我们可以用group_by()分组后,结合rep()的length.out参数来生成循环的交替序列,具体代码如下:
df |> group_by(group) |> mutate( B = ifelse( A == "c", # 生成长度匹配当前组内A=="c"行数的交替序列 rep(c("x", "y"), length.out = sum(A == "c")), B # 不满足条件时保留原B值 ) ) |> ungroup() # 取消分组(可选,根据后续操作需求)
为什么你的原代码不行?
你之前用了rep(c("x", "y"), each = 0.5 * sum(A == "c")),这里有两个问题:
each参数是用来重复每个元素的次数,比如rep(c("x","y"), each=2)会得到c("x","x","y","y"),这和你想要的交替x,y,x,y不符;- 如果组内
A=="c"的行数是奇数,0.5 * sum(...)会得到小数,rep不接受非整数的each参数,直接报错。
而用length.out参数的话,不管组内符合条件的行数是奇数还是偶数,都会自动循环填充x和y,完美匹配你的交替需求。
运行结果验证
执行上面的代码后,输出正好符合你的预期:
# A tibble: 8 × 3 group A B <chr> <chr> <chr> 1 a c x 2 a d b 3 a c y 4 a d d 5 b c x 6 b d f 7 b c y 8 b d h
备注:内容来源于stack exchange,提问作者deschen
相关产品推荐
相关产品推荐

