Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional dataframe mutations in R with magrittr and dplyr

Tags:

r

dplyr

magrittr

I would like to use the succinctness of magrittr and dplyr to copy single values between rows in a subset of columns based on the values in other columns. This is a simple example; I want to apply this idea to many columns of a large dataset with multiple conditions within a long pipe of commands.

Take the dataframe df <- data.frame(a = 1:5, b = 6:10, x = 11:15, y = 16:20):

a   b   x   y

1   6   11  16
2   7   12  17
3   8   13  18
4   9   14  19
5   10  15  20

For the row where a = 5, I would like to replace the values of x and y with those in the row where b = 7, to give:

a   b   x   y

1   6   11  16
2   7   12  17
3   8   13  18
4   9   14  19
5   10  12  17

This attempt fails:

foo <- function(x){ifelse(df$a == 5, df[df$b == 7, .(df$x)], x)}
df %<>%  mutate_each(funs(foo), x, y)

The closest I can get is:

bar <- function(x){ifelse(df$a == 5, df[df$b == 7, "x"], x)}
df %<>%  mutate_each(funs(bar), x, y)

but this is incorrect as it replaces both values with the value from x, rather than x and y respectively.

Thanks for the advice.

like image 538
Patrick Hogan Avatar asked Dec 08 '15 16:12

Patrick Hogan


1 Answers

You could do it using mutate_each and replace:

df %>% mutate_each(funs(replace(., a==5, nth(., which(b==7)))), x, y)

Output:

  a  b  x  y
1 1  6 11 16
2 2  7 12 17
3 3  8 13 18
4 4  9 14 19
5 5 10 12 17

Or as per @docendodiscimus 's comment it can be shortened further to (and probably [ is also better than which):

df %>% mutate_each(funs(replace(., a==5, .[b==7])), x, y)
like image 144
LyzandeR Avatar answered Nov 05 '22 07:11

LyzandeR