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

问题描述 投票:0回答:3

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

假设这是我的数据(列ab)和列c是我想要的,即a - b但在a时保持b==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解决方案,请分享您的知识。我甚至不知道该尝试什么。

如果您认为它与现有问题重复,则会删除此问题,但现有的线程都没有特别有用。

r subtraction col
3个回答
1
投票

试试这个(Base R Solution):

如果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

1
投票

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

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

如果ab,这里的想法是采取a减去b,或NA。如果整个表达式仍然是NA,那么它暗示a也是NA,在这种情况下我们采取b


0
投票

这里有base R的一个选项,其中我们replace NA元素0,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)))]

data

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")
© www.soinside.com 2019 - 2024. All rights reserved.