提问人:Sam 提问时间:5/18/2023 最后编辑:Darren TsaiSam 更新时间:5/23/2023 访问量:89
如果缺少的列少于 x 列,则替换缺失值
Replace missing values if fewer than x columns missing
问:
我想仅将列中缺失值少于 2 个的行替换为零。然后我想重新计算总和列(我可以很高兴地按照我的 reprex 使用)。var1:var6
var1:var6
rowwise()
我已经尝试了一些使用 ,或者 和 但正在努力寻找解决方案。across()
rowwise()
c_across()
library(tidyverse)
# Generate data
set.seed(40)
dat <- tibble(
id = 1:6,
var1 = sample(c(0:4, NA), 6, replace = TRUE),
var2 = sample(c(0:4, NA), 6, replace = TRUE),
var3 = sample(c(0:4, NA), 6, replace = TRUE),
var4 = sample(c(0:4, NA), 6, replace = TRUE),
var5 = sample(c(0:4, NA), 6, replace = TRUE),
var6 = sample(c(0:4, NA), 6, replace = TRUE),
)
dat %>%
rowwise() %>%
mutate(sum = sum(c_across(var1:var6))) %>%
ungroup()
这是当前的 tibble:
> dat
# A tibble: 6 × 8
id var1 var2 var3 var4 var5 var6 sum
<int> <int> <int> <int> <int> <int> <int> <int>
1 1 3 4 4 NA NA 2 NA
2 2 NA NA 4 3 4 2 NA
3 3 4 4 1 1 4 1 15
4 4 1 2 4 4 4 NA NA
5 5 2 1 4 4 NA 2 NA
6 6 1 3 1 0 0 4 9
我希望输出如下所示:
> new_dat
# A tibble: 6 × 8
id var1 var2 var3 var4 var5 var6 sum
<int> <int> <int> <int> <int> <int> <int> <int>
1 1 3 4 4 NA NA 2 NA
2 2 NA NA 4 3 4 2 NA
3 3 4 4 1 1 4 1 15
4 4 1 2 4 4 4 0 15
5 5 2 1 4 4 0 2 13
6 6 1 3 1 0 0 4 9
答:
5赞
Maël
5/18/2023
#1
您可以像这样使用:across
dat %>%
mutate(across(var1:var6, ~ replace(.x, is.na(.x) & rowSums(is.na(across(var1:var6))) < 2, 0)),
sum = rowSums(across(var1:var6)))
# # A tibble: 6 × 8
# id var1 var2 var3 var4 var5 var6 sum
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 3 4 4 NA NA 2 NA
# 2 2 NA NA 4 3 4 2 NA
# 3 3 4 4 1 1 4 1 15
# 4 4 1 2 4 4 4 0 15
# 5 5 2 1 4 4 0 2 13
# 6 6 1 3 1 0 0 4 9
3赞
Darren Tsai
5/18/2023
#2
若要使用 对代码进行最小程度的调整,可以将参数设置为灵活的逻辑值,以指示该行的缺失值是否少于 2。rowwise()
na.rm
sum()
dat %>%
rowwise() %>%
mutate(sum = c_across(var1:var6) %>% sum(na.rm = sum(is.na(.)) < 2)) %>%
ungroup()
# # A tibble: 6 × 8
# id var1 var2 var3 var4 var5 var6 sum
# <int> <int> <int> <int> <int> <int> <int> <int>
# 1 1 3 4 4 NA NA 2 NA
# 2 2 NA NA 4 3 4 2 NA
# 3 3 4 4 1 1 4 1 15
# 4 4 1 2 4 4 4 NA 15
# 5 5 2 1 4 4 NA 2 13
# 6 6 1 3 1 0 0 4 9
评论
1赞
Maël
5/18/2023
哇,不知道这个招数!我一定会把它添加到我的日常生活中na.rm
0赞
zx8754
5/18/2023
我认为您需要在第 4 行和第 5 行将 NA 转换为 0。
0赞
Sam
5/18/2023
很棒的技巧,也奏效了。我接受了 Maël 的回答,因为它最适合我的其余部分。但是你的回答很优雅!
0赞
diomedesdata
5/18/2023
我真的很困惑是什么在这里扮演了第一个论点的角色。来自其他任何人的文档:......如果占位符仅在嵌套函数调用中使用,则 LHS 也将作为第一个参数放置!这样做的原因是,在大多数用例中,这会生成最易读的代码。例如,相当于但稍微紧凑一些。sum
iris %>% subset(1:nrow(.) %% 2 == 0)
iris %>% subset(., 1:nrow(.) %% 2 == 0)
2赞
zx8754
5/18/2023
#3
基本替代方案,如果 NA 最多出现一次,则将 NA 转换为 0。然后像往常一样获取 rowSums:
cc <- grep("^var", colnames(dat), value = TRUE)
rr <- which(rowSums(is.na(dat[ cc ])) < 2)
dat[ rr, cc ][ is.na(dat[ rr, cc ]) ] <- 0
dat$sum <- rowSums(dat[ cc ])
# id var1 var2 var3 var4 var5 var6 sum
# 1 1 3 4 4 NA NA 2 NA
# 2 2 NA NA 4 3 4 2 NA
# 3 3 4 4 1 1 4 1 15
# 4 4 1 2 4 4 4 0 15
# 5 5 2 1 4 4 0 2 13
# 6 6 1 3 1 0 0 4 9
评论