Overwrite lot of columns with mutate_at in R?

2019-08-05 11:14发布

问题:

Given the following dataframe I am trying to mutate all but c and d columns using dplyr::mutate_at with lambda function but without luck:

structure(list(a = c(1, 2, 3), b = c(43, 2, -1), c = c(234242, 
-223, 1), d = c(1, 1, 2)), .Names = c("a", "b", "c", "d"), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"))

df %>% mutate_at(vars(-c("c", "d"), funs(x = x + rnorm(1, mean = mean(x), sd = sd(x))

I want to overwrite the existing a and b columns without the need to mutate each other manually. Please advise.

NOTE: My real dataset is similar but it has 50 columns to mutate and add this normal distribution random variable value. I want to automate it except for specific columns.

回答1:

You were nearly there. Two little things to change:

  1. Change x to .
  2. Access the column names without quote marks: -c(c, d) instead of -c("c", "d").

This leads to

df %>% mutate_at(vars(-c(c, d)), funs(. + rnorm(1, mean = mean(.), sd = sd(.))))                                    

which works fine. Output is:

# A tibble: 3 x 4
      a     b       c     d
  <dbl> <dbl>   <dbl> <dbl>
1  3.05  56.6  234242     1
2  4.05  15.6    -223     1
3  5.05  12.6       1     2


回答2:

Just as a side note:

You could use: mutate_if

df1 %>% mutate_if(names(.)%in%c("a","b"), funs(. + rnorm(1, mean = mean(.), sd = sd(.))))

There, of course, you have to use " because you're comparing strings with each other.



回答3:

If all the variables you want to change are in order, you can index them in vars. And you'll want to change x to "."

df %>% mutate_at(vars(a:b), funs(. + rnorm(1, mean = mean(.), sd = sd(.))))
#       a      b       c     d
# 1  3.20  34.2   234242     1
# 2  4.20  -6.85    -223     1
# 3  5.20  -9.85       1     2