0
votes

I'm looking to use a non-across function from mutate to create multiple columns. My problem is that the variable in the function will change along with the crossed variables. Here's an example:

needs=c('Sepal.Length','Petal.Length')
iris %>% mutate_at(needs, ~./'{col}.Width')

This obviously doesn't work, but I'm looking to divide Sepal.Length by Sepal.Width and Petal.Length by Petal.Width.

2

2 Answers

1
votes

I think your needs should be something which is common in both the columns.

You can select the columns based on the pattern in needs and divide the data based on position. !! and := is used to assign name of the new columns.

library(dplyr)
library(rlang)

needs = c('Sepal','Petal')

purrr::map_dfc(needs, ~iris %>% 
                        select(matches(.x)) %>%
                        transmute(!!paste0(.x, '_divide') := .[[1]]/.[[2]]))

#    Sepal_divide Petal_divide
#1    1.457142857  7.000000000
#2    1.633333333  7.000000000
#3    1.468750000  6.500000000
#4    1.483870968  7.500000000
#...
#...

If you want to add these as new columns you can do bind_cols the above with iris.

1
votes

Here is a base R approach based that the columns you want to divide have a similar name pattern,

res <- sapply(split.default(iris[-ncol(iris)], sub('\\..*', '', names(iris[-ncol(iris)]))), function(i) i[1] / i[2])
iris[names(res)] <- res
head(iris)

#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Petal.Petal.Length Sepal.Sepal.Length
#1          5.1         3.5          1.4         0.2  setosa               7.00           1.457143
#2          4.9         3.0          1.4         0.2  setosa               7.00           1.633333
#3          4.7         3.2          1.3         0.2  setosa               6.50           1.468750
#4          4.6         3.1          1.5         0.2  setosa               7.50           1.483871
#5          5.0         3.6          1.4         0.2  setosa               7.00           1.388889
#6          5.4         3.9          1.7         0.4  setosa               4.25           1.384615