替换一个由数据框列表组成的列表中的列,使用另一个由数据框列表组成的列表中的列。R

3

我有两个列表,格式如下:

   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")))

并且

    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")))

我的目标是替换a[[1]][[i]]$x <- b[[1]][[i]]$x

当两个数据框在列表之外时,这是相当简单的:

df1$x<-df2$x

然而,使用我编写的代码并没有起作用。
replacex<-function(onelist, anotherlist){

newlist<-list() #for storage
onelist$x<-anotherlist$x
newlist<-onelist 
}


Dfs_new_X<-lapply(a,lapply,replacex,anotherlist=b)

它并不会报错,但是它会删除该列。非常感谢您提供的任何帮助。

如果有人能够指出我的代码为什么不起作用,我将不胜感激,这样我就可以学习并避免在未来犯同样的错误。 - JPV
2个回答

2
我们可以使用purrr包中的map2来进行替换。 dat是最终输出结果。
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

我们也可以使用mapply来遵循同样的逻辑。它生成与map2解决方案相同的结果。

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

mapply 解决方案可以简化一下 - a[[1]] <- Map(function(a,b) {a$X <- b$X; a}, a[[1]], b[[1]]) - thelatemail
map2是一个完美的解决方案。我不熟悉purrr,但我认为我需要熟悉一下。只是一个问题:为什么没有return(i),我得到的是一个替换了列而不是整个数据框的列表?return(i)似乎是获取预期输出所必需的。 - JPV
1
@JPV 如果没有返回值,函数会默认返回在该函数中创建的最后一个对象,而在这种情况下是一列数据。 - www

0

最初让我困惑的是,您的示例列表包含了一个不必要的层级。直接读取您的列表并将它们命名为list_1和list_2,您会得到:

  • list_1(包含)> 长度为一的列表(包含)> 两个数据框
  • list_2(包含)> 长度为一的列表(包含)> 两个数据框

然而,更常见的用例可能是以下情况:

  • list_1(包含)> 两个数据框
  • list_2(包含)> 两个数据框

由于没有迹象表明我所描述的“长度为一的列表”层级对于您的示例是必要的,因此我使用以下方法将其删除:

list_1 <- list_1[[1]]
list_2 <- list_2[[1]]

然后,您可以避免使用map2的双重应用程序,而是直接使用dplyr包中的mutate函数。

purrr::map2(list_1, list_2, function(l1, l2){
  dplyr::mutate(l1, X = l2$X)
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接