繁体   English   中英

R:使用 tidyverse 将 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))
})

非常好的问题。 谢谢!

这里我们使用:

  1. rowSums添加一列与 X1-X3 的行总和
  2. 然后我们across所有X进行mutate ,并且
  3. 将每个XrowSum1 coalesce
  4. 令人惊讶的是rowSum1列消失了,因为不需要 ->
  5. 这是由于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM