Reputation: 4201
I have a list object that contains several elements. One element is a data frame that I wish to modify: I want to perform some operations such as column renaming and mutating new columns.
Although one simple way is to extract the nested data frame, modify it, and finally re-assign the output to the original parent list, I'd like to avoid such solution because it requires intermediate assignment.
Data. let's build a list of several data objects
library(tibble)
my_list <- lst(letters, mtcars, co2, uspop, iris)
Task.
I want to modify my_list$mtcars
to:
cyl
columnmpg
columnI want to modify my_list$iris
to:
sepal
and ultimately I expect to get back a list object that is identical to the original my_list
, except for the changes I made for mtcars
and iris
.
My attempt. Right now, the only way I know to achieve this involves re-assignment:
library(dplyr)
my_list$mtcars <-
my_list$mtcars %>%
rename("Number of cylinders" = cyl) %>%
mutate(sqrt_of_mpg = sqrt(mpg))
my_list$iris <-
my_list$iris %>%
select(starts_with("Sepal")) %>%
rename_with(tolower)
My question: Given my_list
, how could I point to a nested element by its name, specify which actions should happen to modify it, and get back the parent my_list
with just those modifications?
I imagine some sort of a pipe that looks like this (just to get my general idea)
## DEMO ##
my_list %>%
update_element(which = "mtcars", what = rename, mutate) %>%
update_element(which = "iris", what = select, rename)
Thanks!
Upvotes: 2
Views: 697
Reputation: 389235
You can use imap
which passes name along with data for each iteration but this is not closer to your general idea.
library(dplyr)
my_list <- purrr::imap(my_list, ~{
if(.y == 'mtcars')
.x %>% rename("Number of cylinders" = cyl) %>%mutate(sqrt_of_mpg = sqrt(mpg))
else if(.y == 'iris')
.x %>% select(starts_with("Sepal")) %>% rename_with(tolower)
else .x
})
Upvotes: 1
Reputation: 17668
You can try purrr
's modify_at
function
library(tidyverse)
my_list %>%
modify_at("mtcars", ~rename(.,"Number of cylinders" = cyl) %>%
mutate(sqrt_of_mpg = sqrt(mpg))) %>%
modify_at("iris", ~select(., starts_with("Sepal")) %>%
rename_with(tolower))
Upvotes: 2