I have a list of lists of dataframes, each having one column, like this:
list(list(A = data.frame(X = 1:5),
B = data.frame(Y = 6:10),
C = data.frame(Z = 11:15)),
list(A = data.frame(X = 16:20),
B = data.frame(Y = 21:25),
C = data.frame(Z = 26:30)),
list(A = data.frame(X = 31:35),
B = data.frame(Y = 36:40),
C = data.frame(Z = 41:45))) -> dflist
I need to make it so that the column names X, Y and Z inside of each dataframe are changed to A, B and C. An important thing to add is that the names A, B and C are not known beforehand, but must be extracted from the list element names. I have a simple script that can accomplish this:
for(i in 1:3){
for(j in 1:3){
colnames(dflist[[i]][[j]]) <- names(dflist[[i]])[[j]]
}
}
However, I need to do this in tidyverse style. I have found similar questions on here, however, they only deal with lists of dataframes and not with lists of lists of dataframes and I can't find a way to make it work.
CodePudding user response:
Using combination of map
and imap
-
library(dplyr)
library(purrr)
map(dflist, function(x)
imap(x, function(data, name)
data %>% rename_with(function(y) name)))
#[[1]]
#[[1]]$A
# A
#1 1
#2 2
#3 3
#4 4
#5 5
#[[1]]$B
# B
#1 6
#2 7
#3 8
#4 9
#5 10
#[[1]]$C
# C
#1 11
#2 12
#3 13
#4 14
#5 15
#...
#...
CodePudding user response:
Also possible without purrr, using lapply
and mapply
(the latter with SIMPLIFY=FALSE
). If dflist
is your list of lists:
lapply(dflist, function(x){
mapply(function(y,z){
`colnames<-`(y, z)
}, y=x, z=names(x), SIMPLIFY=F)
})
#or on one line:
lapply(dflist, function(x) mapply(function(y,z) `colnames<-`(y, z), y=x, z=names(x), SIMPLIFY=F))
CodePudding user response:
A solution with purrr:walk
:
library(tidyverse)
walk(1:length(dflist),
function(x)
walk(names(dflist[[x]]), ~ {names(dflist[[x]][[.x]]) <<- .x}))