8

I'm fairly new to R and have run into an issue with NA's. This question may have been answered elsewhere but I can't seem to find the answer. I'm trying to do sort of the opposite of rowSums() in that I'm trying to subtract x2 and x3 from x1 in order to generate x4 without NA's. The code I'm currently using is as follows:

> x <- data.frame(x1 = 3, x2 = c(4:1, 2:5), x3=c(1,NA))
> x$x4=x$x1-x$x2-x$x3
> x

  x1 x2 x3 x4
1  3  4  1 -2
2  3  3 NA NA
3  3  2  1  0
4  3  1 NA NA
5  3  2  1  0
6  3  3 NA NA
7  3  4  1 -2
8  3  5 NA NA

In other words I want to ingore the NA's similar to how rowSums allows the na.rm=TRUE argument so that I get this result:

  x1 x2 x3 x4
1  3  4  1 -2
2  3  3 NA  0
3  3  2  1  0
4  3  1 NA  2
5  3  2  1  0
6  3  3 NA  0
7  3  4  1 -2
8  3  5 NA -2

Any help is greatly appreciated.

sgibb
  • 25,396
  • 3
  • 68
  • 74
rmbaughman
  • 921
  • 1
  • 7
  • 17

2 Answers2

6

You can use something like this if all columns have NAs -

x$x4 <- ifelse(is.na(x$x1),0,x$x1) -ifelse(is.na(x$x2),0,x$x2)-ifelse(is.na(x$x3),0,x$x3)

Provided you want to treat NAs as 0. Else you can replace the 0s in the above formula with the value you need.

RHelp
  • 815
  • 2
  • 8
  • 23
3

Just use rowSums:

> x$x4 <- x$x1 - rowSums(x[,2:3], na.rm=TRUE)
> x
  x1 x2 x3 x4
1  3  4  1 -2
2  3  3 NA  0
3  3  2  1  0
4  3  1 NA  2
5  3  2  1  0
6  3  3 NA  0
7  3  4  1 -2
8  3  5 NA -2
Thomas
  • 43,637
  • 12
  • 109
  • 140
  • 2
    Any idea how to approach this problem if x1 & x2 also contained NA's? – rmbaughman Apr 23 '14 at 21:37
  • @user3498787 How do you want the `NA`s handled? Are they treated as zeroes (as in my answer) or do you want `NA`s where `x1==NA`? – Thomas Apr 23 '14 at 21:38
  • Sorry, I meant to say if x1 contained NA's. Using your answer and RHelps's answer below it looks like I could combine both to solve it this way: x$x4 <- ifelse(is.na(x$x1,0,x$x1) - rowSums(x[,2:3], na.rm=TRUE) – rmbaughman Apr 24 '14 at 12:33
  • 2
    You probably want something like `ifelse(!is.na(x$x1), x$x1 - rowSums(x[,2:3], na.rm=TRUE), 0 - rowSums(x[,2:3], na.rm=TRUE))` – Thomas Apr 24 '14 at 13:19