user3206440
user3206440

Reputation: 5059

iterate through a list of data frames and mutate columns

with data frames like below, I want to use a for loop to iterate through each data frame and add some new column say new & new1 to the data frames d1 and d2. Below is what I have tried.

d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)

for(df in my.list) {
  df$new <- df$y1 + df$y2
  df$new1 <- df$y1 - df$y2
}

However when I look at the original data frames d1 and d2 they do not show the new col new.

> colnames(d1)
[1] "y1" "y2"
> colnames(d2)
[1] "y1" "y2"

How do I got about getting new columns added to the original data frames d1 and d2 ?

Upvotes: 5

Views: 1728

Answers (4)

Jannik Buhr
Jannik Buhr

Reputation: 1957

The map-version looks as follows:

library(purrr) # part of the tidyverse
map(my.list, ~ mutate(.x, new = y1 + y2))

~ creates and anonymous function.

Upvotes: 3

akrun
akrun

Reputation: 887691

here is an option with lapply

lst <- lapply(my.list, transform, new = y1 + y2, new1 = y1 - y2)

It is better to keep the 'data.frame's in the list and not to update the objects on the global environment. But, if it is really needed

list2env(lst, envir = .GlobalEnv)
d1
#  y1 y2 new new1
#1  1  4   5   -3
#2  2  5   7   -3
#3  3  6   9   -3

data

my.list <- mget(paste0("d", 1:2))

Upvotes: 2

bala83
bala83

Reputation: 443

Do this instead:

for(df in 1:length(my.list)) { my.list[[df]]$new <- my.list[[df]]$y1 + my.list[[df]]$y2 }

Upvotes: 0

Russ Hyde
Russ Hyde

Reputation: 2269

Use lapply or Map/map, rather than for.

lapply(my.list, function(df) {df$new <- df$y1 + df$y2; df})

Upvotes: 0

Related Questions