我有两个列表合并两个列表中的R
first = list(a = 1, b = 2, c = 3)
second = list(a = 2, b = 3, c = 4)
我想这样的最终产品是
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
合并这两个列表有一个简单的函数来做到这一点?
我有两个列表合并两个列表中的R
first = list(a = 1, b = 2, c = 3)
second = list(a = 2, b = 3, c = 4)
我想这样的最终产品是
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
合并这两个列表有一个简单的函数来做到这一点?
如果列表中始终具有相同的结构,作为例子,那么简单的解决方案是
mapply(c, first, second, SIMPLIFY=FALSE)
这相当于'Map(c,first,second)',如果有人在意。 – Masterfool 2015-07-17 21:56:30
我刚刚学习R,为什么Map(和mapply)具有'c'作为第一个参数?参数传递的参数不应该是两个列表吗? – user391339 2016-06-01 15:59:03
'c'是创建列表的原始函数的名称。在R中输入c而没有尾随parens显示'function(...,recursive = FALSE).Primitive(“c”)'因此,这个陈词滥调将'c'函数映射为第一个和第二个内容。 – 2016-06-28 16:29:17
这里有两种选择,第一种:
both <- list(first, second)
n <- unique(unlist(lapply(both, names)))
names(n) <- n
lapply(n, function(ni) unlist(lapply(both, `[[`, ni)))
;第二,只有当它们具有相同的结构,工作原理:
apply(cbind(first, second),1,function(x) unname(unlist(x)))
均可以得到想要的结果。
我不认为你的第二个一个正常工作,因为我得到一个矩阵设计,而不是一个向量列表。 – 2012-03-01 17:16:04
你是对的;如果可以的话,“apply”可以简化它。如果它不能简化,它会起作用,例如,如果'first $ c < - c(4,5)',例如。 – Aaron 2012-03-01 18:52:31
第一个给我一个长度= 0的列表。名称应该被定义为某些东西? – 2017-09-26 19:44:57
这是萨卡的modifyList功能的一个非常简单的适应。因为它是递归的,所以它会处理比mapply
更复杂的情况,它将通过忽略“第二”中不属于“第一”的项来处理不匹配的名称情况。
appendList <- function (x, val)
{
stopifnot(is.list(x), is.list(val))
xnames <- names(x)
for (v in names(val)) {
x[[v]] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]]))
appendList(x[[v]], val[[v]])
else c(x[[v]], val[[v]])
}
x
}
> appendList(first,second)
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
下面是一些代码,我根据@安德烈的回答写了一些代码,但没有优美/简单。其优点是,它允许一个更复杂的递归合并也不同,应与rbind
连接那些刚刚与c
连接的元素,且这些之间:
# Decided to move this outside the mapply, not sure this is
# that important for speed but I imagine redefining the function
# might be somewhat time-consuming
mergeLists_internal <- function(o_element, n_element){
if (is.list(n_element)){
# Fill in non-existant element with NA elements
if (length(n_element) != length(o_element)){
n_unique <- names(n_element)[! names(n_element) %in% names(o_element)]
if (length(n_unique) > 0){
for (n in n_unique){
if (is.matrix(n_element[[n]])){
o_element[[n]] <- matrix(NA,
nrow=nrow(n_element[[n]]),
ncol=ncol(n_element[[n]]))
}else{
o_element[[n]] <- rep(NA,
times=length(n_element[[n]]))
}
}
}
o_unique <- names(o_element)[! names(o_element) %in% names(n_element)]
if (length(o_unique) > 0){
for (n in o_unique){
if (is.matrix(n_element[[n]])){
n_element[[n]] <- matrix(NA,
nrow=nrow(o_element[[n]]),
ncol=ncol(o_element[[n]]))
}else{
n_element[[n]] <- rep(NA,
times=length(o_element[[n]]))
}
}
}
}
# Now merge the two lists
return(mergeLists(o_element,
n_element))
}
if(length(n_element)>1){
new_cols <- ifelse(is.matrix(n_element), ncol(n_element), length(n_element))
old_cols <- ifelse(is.matrix(o_element), ncol(o_element), length(o_element))
if (new_cols != old_cols)
stop("Your length doesn't match on the elements,",
" new element (", new_cols , ") !=",
" old element (", old_cols , ")")
}
return(rbind(o_element,
n_element,
deparse.level=0))
return(c(o_element,
n_element))
}
mergeLists <- function(old, new){
if (is.null(old))
return (new)
m <- mapply(mergeLists_internal, old, new, SIMPLIFY=FALSE)
return(m)
}
这里是我的例子:
v1 <- list("a"=c(1,2), b="test 1", sublist=list(one=20:21, two=21:22))
v2 <- list("a"=c(3,4), b="test 2", sublist=list(one=10:11, two=11:12, three=1:2))
mergeLists(v1, v2)
这结果:
$a
[,1] [,2]
[1,] 1 2
[2,] 3 4
$b
[1] "test 1" "test 2"
$sublist
$sublist$one
[,1] [,2]
[1,] 20 21
[2,] 10 11
$sublist$two
[,1] [,2]
[1,] 21 22
[2,] 11 12
$sublist$three
[,1] [,2]
[1,] NA NA
[2,] 1 2
是啊,我知道 - 也许不是最合乎逻辑的合并,但我有一个复杂的并行循环,我公顷d,以产生更多自定义功能.combine
,所以我写了这个怪物:-)
在可能一般的,
merge_list <- function(...) by(v<-unlist(c(...)),names(v),base::c)
注意,by()
液返回attribute
d列表,因此它会打印不同,但仍然是一个列表。但你可以用attr(x,"_attribute.name_")<-NULL
摆脱属性。你也可以使用aggregate()
。
list3 <- append(list1, list2)
还将努力
检查:http://stackoverflow.com/questions/7349608/merge-contents-within-list-of-list-by-duplicate-name – Hansi 2012-03-01 16:10:38