我想在R中从另一列中减去一列,结果比我想象的更复杂。
假设这是我的数据(列a
和b
)和列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
解决方案,请分享您的知识。我甚至不知道该尝试什么。
如果您认为它与现有问题重复,则会删除此问题,但现有的线程都没有特别有用。
试试这个(Base R Solution):
如果df$b
是NA
然后简单地取df$a
的值,如果df$a
是NA
然后简单地取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
您可以尝试使用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
如果a
是b
,这里的想法是采取a
减去b
,或NA
。如果整个表达式仍然是NA
,那么它暗示a
也是NA
,在这种情况下我们采取b
。
这里有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)))]
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")