简体   繁体   中英

Mutate dataframes in a nested list without for loop

I have a list of dataframes (and parameters for sensitivity analyses for a study), and I want to mutate each dataframe in the same way. The expected output is generated by the code below (a new column x2 ). Is there a way to assign the resulting dataframes ( newdfs ) to the list without using a for loop?

models <- list(m1 = list('params' = list('start'='2014-01-01'),
                         'data' = data.frame(y=c(1,2,3), x1=c(4,5,6))),
               m2 = list('params' = list('start'='2017-01-01'),
                         'data' = data.frame(y=c(1,2,3), x1=c(7,8,9))))

newdfs <- lapply(models, function(z) {z$data$x2 <- z$data$x1 + 1
                                      z$data})

# Can I do this without "for"? 
for(x in 1:length(models)) models[[x]]$data <- newdfs[[x]]

You can try this:

newdfs <- lapply(models, function(z) {z$data$x2 <- z$data$x1 + 1
return(z)})

$m1
$m1$params
$m1$params$start
[1] "2014-01-01"


$m1$data
  y x1 x2
1 1  4  5
2 2  5  6
3 3  6  7


$m2
$m2$params
$m2$params$start
[1] "2017-01-01"


$m2$data
  y x1 x2
1 1  7  8
2 2  8  9
3 3  9 10

Revise the function in lapply() to return z instead of z$data :

lapply(models, function(z) {z$data$x2 <- z$data$x1 + 1 ; z})

To make this question complete, here are two purrr solutions:

library(purrr)
  1. map() + map_at()
map(models, map_at, "data", transform, x2 = x1 + 1)
  1. transpose() + map()
models %>%
  transpose %>% 
  `[[<-`(., "data", map(.$data, transform, x2 = x1 + 1)) %>%
  transpose

Output

$m1
$m1$params
$m1$params$start
[1] "2014-01-01"


$m1$data
  y x1 x2
1 1  4  5
2 2  5  6
3 3  6  7


$m2
$m2$params
$m2$params$start
[1] "2017-01-01"


$m2$data
  y x1 x2
1 1  7  8
2 2  8  9
3 3  9 10

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM