[英]With tidyverse in R there is something similar as colSums(is.na(df))?
[英]R: Replace NA with other variables in the df using tidyverse
我想用tidyverse替换我的df中的NA值,我想要的值应该从其他cols中计算出来:
输入:
ID, X1, X2, X3,
"A", 0.96, NA, 0.97,
"B", 1.00, NA, 1.01,
"C", 0.98, 0.03, NA,
"A", 1.00, NA, 1.00,
"D", NA, 0.05, 0.99,
我的愿望是在每一行中找到所有三个X1, X2, X3
的哪个变量是 NA 并用其他两个变量的总和来计算它
output:
ID, X1, X2, X3,
"A", 0.96, 1.93, 0.97,
"B", 1.00, 2.01, 1.01,
"C", 0.98, 0.03, 1.01,
"A", 1.00, 2.00, 1.00,
"D", 1.04, 0.05, 0.99,
谢谢!
将NA
值替换为行中其他非 NA 值的sum
。
这可以使用基础 R apply
来完成 -
df[-1] <- t(apply(df[-1], 1, function(x)
replace(x, is.na(x), sum(x, na.rm = TRUE))))
df
# ID X1 X2 X3
#1 A 0.96 1.93 0.97
#2 B 1.00 2.01 1.01
#3 C 0.98 0.03 1.01
#4 A 1.00 2.00 1.00
#5 D 1.04 0.05 0.99
与purrr::pmap_df
类似 -
df[-1] <- purrr::pmap_df(df[-1], ~{
x <- c(...)
replace(x, is.na(x), sum(x, na.rm = TRUE))
})
非常好的问题。 谢谢!
这里我们使用:
rowSums
添加一列与 X1-X3 的行总和across
所有X
进行mutate
,并且X
与rowSum1
coalesce
rowSum1
列消失了,因为不需要 ->mutate
的奇妙.keep="unused"
论点library(tidyverse)
df %>%
mutate(rowsum1 = rowSums(select(., starts_with("X")), na.rm=TRUE)) %>%
mutate(across(starts_with("X"), ~coalesce(.,rowsum1)),.keep="unused")
Output:
ID X1 X2 X3
<chr> <dbl> <dbl> <dbl>
1 A 0.96 1.93 0.97
2 B 1 2.01 1.01
3 C 0.98 0.03 1.01
4 A 1 2 1
5 D 1.04 0.05 0.99
类似于Ronak Shah 的purrr
版本,但保留 ID 列是这样的:
library(purrr)
pmap_df(df, \(...) {
vars <- list(...)
map(vars, ~ ifelse(is.na(.), do.call(sum, c(vars[-1], na.rm = T)), .))
})
使用dplyr::cur_data()
的另一种方法
df %>% rowwise() %>%
mutate(replace(cur_data()[-1], is.na(cur_data()[-1]), sum(cur_data()[-1], na.rm = T)))
# A tibble: 5 x 4
# Rowwise:
ID X1 X2 X3
<chr> <dbl> <dbl> <dbl>
1 A 0.96 1.93 0.97
2 B 1 2.01 1.01
3 C 0.98 0.03 1.01
4 A 1 2 1
5 D 1.04 0.05 0.99
或不使用rowwise
而是across
cross
df %>% mutate(across(starts_with('X'), ~ ifelse(is.na(.), rowSums(cur_data()[-1], na.rm = T), .)))
ID X1 X2 X3
1 A 0.96 1.93 0.97
2 B 1.00 2.01 1.01
3 C 0.98 0.03 1.01
4 A 1.00 2.00 1.00
5 D 1.04 0.05 0.99
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.