Reputation: 4309
In a list of data frames: (mylist<-list(iris, mtcars, ToothGrowth)
), how can I make a change only to specific columns within the list?
For example, I have a character vector (test
) that gives the column names"Petal.Width"
and "drat"
. How can I match these names to column names in my list of data frames and apply something like log(x + 1)
?
So far I am able to get the required columns out on their own, but I'm not sure how to keep the whole list of data frames together and just alter a couple of columns. Thank you
Upvotes: 4
Views: 746
Reputation: 887028
Another option is to use intersect
with the names of the columns to avoid getting the warnings
library(tidyverse)
out <- mylist %>%
map(~ .x %>%
mutate_at(vars(intersect(names(.), test)), myfun))
mylist<-list(iris, mtcars, ToothGrowth)
myfun <- function(x) {
log(x + 1)
}
test <- c("Petal.Width", "drat")
Upvotes: 1
Reputation: 33782
I'd first define the function you want to apply, in your example log(x + 1)
:
myfun <- function(x) {
log(x + 1)
}
Then use purrr::map
to go through the list and dplyr::mutate_at
to match the column names:
library(tidyverse)
mylist %>%
map(~mutate_at(.x, vars(one_of(c("Petal.Width", "drat"))), myfun))
Note this will give warnings because not all data frames contain the columns. You could use matches()
instead if the warnings bother you:
mylist %>%
map(~mutate_at(.x, vars(matches("^Petal\\.Width|drat$")), myfun))
Upvotes: 2
Reputation: 388862
We can do this in couple of steps
test <- c("Petal.Width", "drat")
#Calculate the new value only for those specific columns which we need
value_cols <- lapply(mylist, function(x) log(x[names(x) %in% test]))
value_cols
contains values for columns which we need to change.
We then use mapply
and select specific columns from each list and update their values.
mapply(function(x, y) {
x[names(x) %in% test] <- y
x }, mylist, value_cols)
where value_cols
is
value_cols
#[[1]]
# Petal.Width
#1 -1.60943791
#2 -1.60943791
#3 -1.60943791
#4 -1.60943791
#5 -1.60943791
#...
#...
#[[2]]
# drat
#Mazda RX4 1.360977
#Mazda RX4 Wag 1.360977
#Datsun 710 1.348073
#Hornet 4 Drive 1.124930
#Hornet Sportabout 1.147402
#...
#...
#[[3]]
#data frame with 0 columns and 60 rows
Upvotes: 1