【问题标题】:Concatenate lists with same .names连接具有相同 .names 的列表
【发布时间】:2012-10-03 07:14:12
【问题描述】:

我有同名的列表 v1 和 v2:

v1: structure(list(ID = c("A1"), Name = c("A2"),.Names = c("ID", "Name") 
    ...
v2: structure(list(ID = c("B1"), Name = c("B2"),.Names = c("ID", "Name") 

我想连接列表,同时保留名称,即得到如下内容:

v12:  structure(list(ID = c("A1","B1"), Name = c("A2","B2"), 
.Names = c("ID", "Name")

手动连接有效:

v12<-cbind(Map(c, v1, v2))

但是,如果 v1 和 v2 是应用 lapply() 的结果,并且它们本身存储在一个列表中,类似的逻辑似乎不起作用:

v<-lapply(...)
v12<-cbind(Map(c,v))

自动化流程的最佳方法是什么?例如:

v1 <- structure(list(ID = c("A1"), Name = c("A2")),.Names = c("ID", "Name"))             
v2 <-  structure(list(ID = c("B1"), Name = c("B2")),.Names = c("ID", "Name"))
v <- list(v1, v2)
k<-t(mapply(c, v))

结果:

ID  Name
A1  A2
B1  B2

不在:

  ID    Name
"A1","B1"   "A2","B2"

【问题讨论】:

  • 你的问题很混乱。它提到了cbind,但我认为您实际上是在寻找rbind。你提到了lists,但看起来你实际上指的是data.frames。您能否尝试发布一些可重现的代码。请参阅this post 了解一些提示。
  • 感谢 Sven,代码是这样的:'v1
  • @sven-hohenstein,感谢您的回复,但您的代码导致:ID Name 1 A1 A2 2 B1 B2 虽然我迫切需要:ID Name 1 "A1","A2" "B1" ,"B2"
  • 您的迫切需要完全不清楚。你需要的东西的结构是什么?显示它的印刷表示并不能告诉我们它的内部表示。

标签: r list matrix


【解决方案1】:

这个怎么样?

> data.frame(ID = do.call("paste", c(lapply(v, FUN = "[", "ID"), sep = ",")), 
+    Name = do.call("paste", c(lapply(v, FUN = "[", "Name"), sep = ",")))
     ID  Name
1 A1,B1 A2,B2

【讨论】:

  • 很好的解决方案,但是如果列表中有 100 个名字怎么办?我是否应该为每个 Name1..Name100 明确定义每一个(即 NameX=do.call("paste", c(lapply(v, FUN = "[", "NameX"), sep = ",")) ),还是有更快的方法?
  • 对于许多名称,我会使用一些不同的方法。 @mrdwab 的解决方案很容易扩展到一个冗长的名称列表。尽管如此,如果您想进一步寻求此解决方案,请告诉我们。
  • 你会推荐什么内存使用方式?
【解决方案2】:

我觉得你的问题非常不清楚,但也许你可以试试:

setNames(Reduce(function(x, y) paste(x, y, sep = ", "), v), 
         c("ID", "Name"))
#       ID     Name 
# "A1, B1" "A2, B2"

或者,也可以在其中添加t()

t(setNames(Reduce(function(x, y) paste(x, y, sep = ", "), v), 
           c("ID", "Name")))
     ID       Name    
[1,] "A1, B1" "A2, B2"

【讨论】:

    【解决方案3】:

    如果我理解正确,您想要一个与其他两个具有相同结构但元素合并的列表。在这种情况下,试试这个:

    ul <- unlist(list(v1,v2))
    sapply(unique(names(ul)),function(x) as.vector(ul[names(ul)%in%x]),simplify=FALSE)
    $ID
    [1] "A1" "B1"
    
    $Name
    [1] "A2" "B2"
    

    【讨论】:

      【解决方案4】:

      一个想法::

      v1 <- structure(list(ID = c("A1"), Name = c("A2")),.Names = c("ID", "Name"))
      v2 <-  structure(list(ID = c("B1"), Name = c("B2")),.Names = c("ID", "Name"))
      v <- list(v1, v2)
      
      
      t(mapply(c, v)) # output as matrix
      

      第二次尝试:

      unlist(apply(mapply(c,v), 1, function(x) list(unlist(x))), recursive = FALSE)
      # output as list
      

      更新:如果您想在每个列表中拥有唯一值,请使用:

      v3 <- list(ID = "B1", Name = "B3")
      vx <- list(v1, v2, v3)
      
      unlist(apply(mapply(c,vx), 1,
                   function(x) list(unique(unlist(x)))), recursive = FALSE)
      

      【讨论】:

      • 谢谢,似乎有效。如果我在 v1 和 v2 中有一些类似的元素,并且不想重复计算怎么办?
      • @斯文谢谢。非常感谢!我为这个问题的措辞不当道歉,我的意思是——如果我的列表矩阵中有 N 个确切的列表,我如何忽略 N-1 个重复项并且该函数只返回 1 个代表以及其他列表?来自 - $ ID : chr [1:3] "A1" "B1" "B1" "A1" $ Name: chr [1:3] "A2" "B2" "B3" "A2" 期望结果 - $ ID :字符 [1:3] "A1" "B1" "B1" $ 名称:字符 [1:3] "A2" "B2" "B3"
      • 我认为它与 duplicate 有关,现在正在调查它
      • @Alex 我回答的最后一个命令不会产生你想要的结果吗?
      • 是的,如果重复项仅存储在一行中。如果不是,我想使用 for(...) 进行逐列扫描是不可避免的,似乎
      猜你喜欢
      • 1970-01-01
      • 2012-06-02
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2013-04-19
      • 1970-01-01
      相关资源
      最近更新 更多