R语言:多行数据的条件值抑制处理问题求助
行级数据抑制的dplyr解决方案
需求说明
- 每行中小于6的值替换为-1
- 若某行仅有1个被抑制值(即原本仅1个值<6),需将该行次小值也替换为-1(即使次小值>5)
- 若所有值均不大于6则保持原样
示例数据
df <- data.frame(list(w = c(7, 25, 9, 50), x = c(1, 25, 9, 50), y = c(6, 35, 1, 6), z = c(4,50, 1, 1)))
期望输出
w x y z 1 7 -1 6 -1 2 25 25 35 50 3 9 9 -1 -1 4 50 50 -1 -1
用户尝试的代码(未正常运行)
df |> pivot_longer(cols = everything(), names_to = 'col', values_to = 'val') |> group_by(col) |> group_map(~.x) |> map(\(x) if(sum(x$val < 6) == 1){ x |> mutate(val = replace(val, val %in% sort(unique(val), partial = 2)[1:2], -1)) }else{ x |> mutate(val = replace(val, val < 6, -1)) }) |> list_rbind(names_to = "col") |> pivot_wider(names_from = col, values_from = val)
正确的dplyr解决方案
核心思路是按行独立处理,通过rowwise()实现行级计算,分场景判断替换逻辑:
library(dplyr) df |> rowwise() |> mutate( across(everything(), ~ { # 获取当前行所有值 row_vals <- c_across(everything()) # 统计小于6的值的数量 less6_count <- sum(row_vals < 6) # 分情况处理 if (all(row_vals <= 6)) { # 所有值都<=6,保持原样 .x } else if (less6_count == 1) { # 仅1个值<6时,替换<6的值和次小值为-1 sorted_vals <- sort(row_vals) if (.x < 6 || .x == sorted_vals[2]) -1 else .x } else { # 其他情况,仅替换<6的值为-1 if (.x < 6) -1 else .x } }) ) |> ungroup()
运行上述代码后,即可得到符合要求的输出。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

