1

Let's say that I have the following dataframe:

df <- data.frame(a=c(1,2,3,3,1), b=(c(1,9,1,2,3)), 
                 c=c(1,2,3,3,9), d=(c(1,2,3,9,1)))

I would like to sum the values of a + b + c + d, but every time that any of these variables has a value of 9, I would like to sum 3 instead of 9.

I know I can do this by re-codifying each of the variables using the following syntax:

df[,1:4][df[,1:4]==9]<-3

but I would like to do it with a temporary table or some code that allows me to skip this step. On top of that, I do not want to miss the original value of each variable, because the 9s will have a meaning for other operations that I need to do.

This would be the result that I would like to have:

df$sum <- c(4,9,10,11,8)

Thank you very much,

Yatrosin

Yatrosin
  • 341
  • 2
  • 15

1 Answers1

1

One option would be to replace elements having values greater than or equal to 9 with 3 and get the rowSums

df$Sum <- rowSums(replace(df[1:4], df[1:4] >= 9, 3))
df$Sum
#[1]  4  9 10 11  8
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    I'd specify the columns explicitly, since if you run this repeatedly in an interactive session, it'll do weird things. I mean with `df[1:4]` (or better, using names) instead of `df`. – Frank Sep 29 '17 at 18:14
  • Yes, of course, this was just a simplified version of the code. In fact, for some columns 9 needs to be consider as a 3 and for other ones, it needs to be consider as 0. – Yatrosin Sep 29 '17 at 18:16
  • @Yatrosin If you need to change different columns with different values, i.e. say 1st 2 columns with 3 and next 2 with 0 `rowSums(do.call(cbind, Map(function(x, y) replace(x, x>=9, y), split.default(df, rep(1:2, each = 2)), c(3, 0))))` – akrun Sep 29 '17 at 18:25
  • @akrun I see this a much complex solution. Can you explain how it works? – Yatrosin Sep 29 '17 at 18:34
  • @Yatrosin Here, we are splitting the dataset into to a `list` with the first 2 columns as one dataset and the next two as other. Then, using `Map` we `replace` the value that are greater than or equal to 9 with corresponding vector elements 3, 0, `cbind` it to make a single data and get the `rowSums` – akrun Sep 29 '17 at 18:54