【问题标题】:Replace column in a list of lists of dataframes with columns in another list of lists of dataframes. R将数据框列表中的列替换为另一个数据框列表中的列。 R
【发布时间】:2019-03-23 20:45:09
【问题描述】:

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

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

My objective is to replace 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)

它不会给出错误,但它会删除该列。

任何帮助将不胜感激。

【问题讨论】:

  • 如果有人对我的代码为什么不工作有发言权,我们将不胜感激,所以要学习,以后不要犯同样的错误。

标签: r list dataframe tidyverse purrr


【解决方案1】:

我们可以使用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]] &lt;- Map(function(a,b) {a$X &lt;- b$X; a}, a[[1]], b[[1]])
  • map2 是一个完美的解决方案。我不熟悉 purrr,但我想我需要熟悉一下。只是一个问题:为什么没有 return(i) 我得到一个替换列而不是整个数据框的列表? return(i) 似乎对于获得预期的输出至关重要。
  • @JPV 如果没有返回,该函数将假定您要返回您在函数中创建的最后一个对象,在本例中为一列。
【解决方案2】:

首先让我感到困惑的是,您的示例列表包含不必要的层。直接读取您的列表并将它们称为 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)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    • 2015-11-14
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多