I have a list of tibbles and use the code below I expect that each tibble in the list will have a column added with a factor (one of 16 levels). I can see exactly what I want being printed to the console, but in the global environment, my list of tibbles remains the same. What am I doing wrong?
fn <- function(df){
df$col1 = cut(df$col1, 16)
return(df)
for (df in listoftibbles){
df <- fn(df)
print (df)
}
In the for
loop, it is not updating the element in listoftibbles
i.e.. if we want to do this, loop over the sequence of the object and update by assignment
for(ind in seq_along(listoftibbles)) {
listoftibbles[[ind]] <- fn(listoftibbles[[ind]])
}
The for
loop in R
is a for each loop which returns the values of the list
element. The 'df' object is a temporary object created on the fly. This can be checked via ls
(suppose there are 2 list elements)
> ls(pattern = '^df$')
character(0) # no object
> for(df in listoftibbles) print(ls(pattern = '^df$'))
[1] "df"
[1] "df"
> ls(pattern = '^df$')
[1] "df" # now there is an object
The value of the object 'df' will be the last tibble
of listoftibbles
and the address can be checked as well
> for(df in listoftibbles) print(tracemem(df))
[1] "<0x7fe59eb4f6c0>"
[1] "<0x7fe598361ac8>"
> tracemem(df) # last object created
[1] "<0x7fe598361ac8>"
We can use lapply
(First posted here)
listoftibbles <- lapply(listoftibbles, fn)
Or this doesn't need any function
listoftibbles <- lapply(listoftibbles, transform, col1 = cut(col1, 16))
or with map
library(dplyr)
library(purrr)
listoftibbles <- map(listoftibbles, mutate, col1 = cut(col1, 16))