Reputation: 323
I have two sets of lists with the following format:
list(list(structure(list(X = c(3L, 4L, 5L, 7L, 2L, 8L, 9L, 6L,
10L, 1L), Y = structure(c(2L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 2L,
1L), .Label = c("no", "yes"), class = "factor")), .Names = c("X",
"Y"), row.names = c(NA, -10L), class = "data.frame"), structure(list(
X = c(3L, 4L, 5L, 7L, 2L, 8L, 9L, 6L, 10L, 1L), Y = structure(c(2L,
2L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 1L), .Label = c("no", "yes"
), class = "factor")), .Names = c("X", "Y"), row.names = c(NA,
-10L), class = "data.frame")))
and
list(list(structure(list(X = c(10L, 3L, 4L, 9L, 8L, 2L, 5L, 7L,
1L, 6L), Y = structure(c(2L, 1L, 2L, 2L, 2L, 1L, 1L, 2L, 1L,
1L), .Label = c("no", "yes"), class = "factor")), .Names = c("X",
"Y"), row.names = c(NA, -10L), class = "data.frame"), structure(list(
X = c(5L, 7L, 4L, 3L, 10L, 2L, 9L, 1L, 8L, 6L), Y = structure(c(2L,
2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L), .Label = c("no", "yes"
), class = "factor")), .Names = c("X", "Y"), row.names = c(NA,
-10L), class = "data.frame")))
My objective is to replace a[[1]][[i]]$x <- b[[1]][[i]]$x
This is fairly simple when two dataframes are outside lists:
df1$x<-df2$x
However with the code I wrote it does not work
replacex<-function(onelist, anotherlist){
newlist<-list() #for storage
onelist$x<-anotherlist$x
newlist<-onelist
}
Dfs_new_X<-lapply(a,lapply,replacex,anotherlist=b)
It does not give an error, but it deletes the column instead.
Any help would be appreciated.
Upvotes: 3
Views: 436
Reputation: 100
What first puzzled me is that your example lists contain an unnecessary layer. Directly reading in your lists and calling them list_1 and list_2 gives you:
However, a more common usecase might be the following:
Since there is no indication that the layer I described as "list of length one" is necessary for your example, I removed it using
list_1 <- list_1[[1]]
list_2 <- list_2[[1]]
Then, you can spare the double application of map2 and simply use mutate from the dplyr package
purrr::map2(list_1, list_2, function(l1, l2){
dplyr::mutate(l1, X = l2$X)
})
Upvotes: 0
Reputation: 39174
We can use map2
from the purrr
package to conduct this replacement. dat
is the final output.
library(purrr)
dat <- map2(a, b, function(x, y){
map2(x, y, function(i, j){
i[["X"]] <- j[["X"]]
return(i)
})
})
dat
# [[1]]
# [[1]][[1]]
# X Y
# 1 10 yes
# 2 3 yes
# 3 4 no
# 4 9 yes
# 5 8 no
# 6 2 yes
# 7 5 no
# 8 7 no
# 9 1 yes
# 10 6 no
#
# [[1]][[2]]
# X Y
# 1 5 yes
# 2 7 yes
# 3 4 no
# 4 3 yes
# 5 10 no
# 6 2 yes
# 7 9 no
# 8 1 no
# 9 8 yes
# 10 6 no
We can also use mapply
following the same logic. It generates the same results as the map2
solution.
dat2 <- mapply(function(x, y){
mapply(function(i, j){
i[["X"]] <- j[["X"]]
return(i)
}, x, y, SIMPLIFY = FALSE)
}, a, b, SIMPLIFY = FALSE)
identical(dat, dat2)
# [1] TRUE
Upvotes: 2