减去 R 数据框中的列,但在另一个为 NA 时保留 var1 或 var2 的值

Subtract columns in R data frame but keep values of var1 or var2 when the other is NA

我想在 R 中从另一列中减去一列,结果比我想象的要复杂。

假设这是我的数据(列 ab)并且列 c 是我想要的,即 a - b 但保留 ab==NA 反之亦然:

   a    b    c
1  2    1    1
2  2   NA    2
3 NA    3    3
4 NA   NA   NA

现在我尝试了不同的方法,但大多数时候当至少一列为 NA 时它返回 NA。例如:

matrixStats::rowDiffs(data, na.rm=T) # only works for matrix-format, and returns NA's

dat$c <- dat$a - dat$b + ifelse(is.na(dat$b),dat$a,0) + ifelse(is.na(dat$a),dat$b,0) # seems like a desparately basic solution, but not even this does the trick as it also returns NA's

apply(dat[,(1:2)], MARGIN = 1,FUN = diff, na.rm=T) # returns NA's

dat$b<-dat$b*(-1)
dat$c<-rowSums(dat,na.rm=T) # this kind of works but it's a really ugly workaround

此外,如果您能想到 dplyr 解决方案,请分享您的知识。我什至不知道该尝试什么。

如果您认为该问题与现有问题重复,将删除该问题,尽管 none 现有话题特别有用。

试试这个(基础 R 解决方案):

如果 df$bNA 那么简单地取值 df$a 否则如果 df$aNA 然后简单地取值 df$b 否则做 df$a-df$b

df$c=ifelse(is.na(df$b),df$a,ifelse(is.na(df$a),df$b,df$a-df$b))

输出:

df
   a  b  c
1  2  1  1
2  2 NA  2
3 NA  3  3
4 NA NA NA

您可以尝试使用 dplyr 包中的 coalesce 函数:

dat <- data.frame(a=c(2, 2, NA, NA), b=c(1, NA, 3, NA))
dat$c <- coalesce(dat$a - coalesce(dat$b, 0), dat$b)
dat$c

   a  b  c
1  2  1  1
2  2 NA  2
3 NA  3  3
4 NA NA NA

这里的想法是 a 减去 b,或者如果 bNA,则单独使用 a。如果整个表达式仍然是 NA,那么它意味着 a 也是 NA,在这种情况下我们采用 b.

这是一个带有 base R 的选项,其中我们 replace 带有 0 的 NA 元素,Reduce 通过按行将其变为单个 vector差异并将具有所有 NA 元素的行更改为 NA

df1$c <- abs(Reduce(`-`, replace(df1, is.na(df1), 0))) *
               NA^ (!rowSums(!is.na(df1)) )
df1$c
#[1]  1  2  3 NA

或使用与 data.table

类似的方法
library(data.table)
setDT(df1)[!is.na(a) | !is.na(b), c := abs(Reduce(`-`, 
               replace(.SD, is.na(.SD), 0)))]

数据

df1 <- structure(list(a = c(2L, 2L, NA, NA), b = c(1L, NA, 3L, NA)), 
 row.names = c("1", "2", "3", "4"), class = "data.frame")