如何使用不同的变量来计算新变量,具体取决于哪个变量有缺失值?

How can I use different variables to calculate a new variable, depending on which variable has missing values?

我想创建一个变量 x,它是变量 e 和其中一个变量 a, b, cd 的乘积。结果变量应取值 a * e,但如果 aNA,则它应取值 b * e,如果缺少 a & b,则它应该取值 c * e 等等。

例如:如果我的数据框如下所示:

df <- data.frame(a = c(1, 2, NA, NA, 5), b = c(NA, 1, NA, 4, 6), c = c(NA, 3, 3, 3, 7), d = c(1, 1, 1, 1, 1), e = c(1, 2, 3, 4, NA))

我希望得到以下结果:

df$x <- c(1, 4, 9, 16, NA)

我正在尝试通过以下方式实现:

df <- df %>% mutate(x = case_when(!is.na(a) ~ a * e, is.na(a) ~ b * e, is.na(a) & is.na(b) ~ c * e, is.na(a) & is.na(b) & is.na(c) ~ d * e))

不幸的是,这还没有工作,因为 R 不知何故不理解 is.na(a) & is.na(b) 因为两个值同时丢失。

df <-
  data.frame(
    a = c(1, 2, NA, NA, 5),
    b = c(NA, 1, NA, 4, 6),
    c = c(NA, 3, 3, 3, 7),
    d = c(1, 1, 1, 1, 1),
    e = c(1, 2, 3, 4, NA)
  )

df$res <- df[, 5] * apply(df[-5], 1, function(x) x[which(x = !is.na(x))[1]])
df
#>    a  b  c d  e res
#> 1  1 NA NA 1  1   1
#> 2  2  1  3 1  2   4
#> 3 NA NA  3 1  3   9
#> 4 NA  4  3 1  4  16
#> 5  5  6  7 1 NA  NA

reprex package (v2.0.1)

于 2022-05-19 创建

这是一个带有 row/column 索引的选项

df$res <- df$e * df[-5][cbind(seq_len(nrow(df)), 
     max.col(!is.na(df[-5]), 'first'))]
df$res
[1]  1  4  9 16 NA

您可以使用 dplyr 中的 coalesce() 来查找第一个 non-missing 元素。

library(dplyr)

df %>%
  mutate(x = e * coalesce(a, b, c, d))

#    a  b  c d  e  x
# 1  1 NA NA 1  1  1
# 2  2  1  3 1  2  4
# 3 NA NA  3 1  3  9
# 4 NA  4  3 1  4 16
# 5  5  6  7 1 NA NA

如果您有很多列要相乘,您可以使用 across() 中的 tidy-selection 自动执行。 (编辑:感谢 @akrun 的改进)

df %>%
  mutate(x = e * do.call(coalesce, across(a:d)))