我在lst
中有一个嵌套列表(所有元素都是类int
)。我事先并不知道lst
的长度;但我知道lst
的每个元素都是长度为k
length(lst[[i]]) # this equals k and is known in advance,
# this is true for i = 1 ... length(lst)
如何获取union
的所有元素的第1个元素,第2个元素,...,第k个元素的lst
具体来说,如果lst
的长度是n
,我想要(不是R代码):
# I know that union can only be taken for 2 elements,
# following is for illustration purposes
listUnion1 <- union(lst[[1, 1]], lst[[2, 1]], ..., lst[[n, 1]])
listUnion2 <- union(lst[[1, 2]], lst[[2, 2]], ..., lst[[n, 2]])
.
.
.
listUnionk <- union(lst[[1, k]], lst[[2, k]], ..., lst[[n, k]])
非常感谢任何帮助或指示。
这是一个可以使用的数据集,n = 3和k = 2
list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12), .Names = c("a", "b")))
答案 0 :(得分:4)
这是一个通用解决方案,与@Ramnath的精神相似,但避免使用union()
这是一个二元函数。诀窍是要注意union()
实现为:
unique(c(as.vector(x), as.vector(y)))
可以通过取消列出每个列表的unique()
组件来实现n
内的位。
完整的解决方案是:
unionFun <- function(n, obj) {
unique(unlist(lapply(obj, `[[`, n)))
}
lapply(seq_along(lst[[1]]), FUN = unionFun, obj = lst)
给出:
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10 11 12
[[2]]
[1] 6 7 8 9 10 11 1 2 3 4 5 12
您显示的数据。
这方面的一些有用功能是:
`[[`
中使用obj
到unionFun
的子集。这与@ Ramnath的答案中的function(x) x$a
相似。但是,我们不需要匿名函数(我们使用`[[`
代替)。相当于@ Ramnath的答案是:lapply(lst, `[[`, 1)
1
替换为n
中的unionFun()
,并允许我们的列表作为参数obj
传递。现在我们有一个函数可以提供给定列表的n
个元素的并集,我们可以lapply()
覆盖索引k
,应用我们的unionFun()
lst
的每个子元素使用lst[[1]]
的长度与所有length(lst[[k]])
的{{1}}相同的事实。
如果在返回的对象中包含k
元素的名称有帮助,我们可以这样做:
n
答案 1 :(得分:3)
这是一个解决方案
# generate dummy data
x1 = sample(letters[1:5], 20, replace = T)
x2 = sample(letters[1:5], 20, replace = T)
df = data.frame(x1, x2, stringsAsFactors = F)
# find unique elements in each column
union_df = apply(df, 2, unique)
让我知道这是否有效
编辑:以下是使用您提供的数据的列表解决方案
mylist = list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12), .Names = c("a", "b")))
list_a = lapply(mylist, function(x) x$a)
list_b = lapply(mylist, function(x) x$b)
union_a = Reduce(union, list_a)
union_b = Reduce(union, list_b)
如果列表中包含的元素超过2个,我们可以对此代码进行概括。
答案 2 :(得分:2)
以下是另一种方法:使用do.call/rbind
按“名称”将列表排列到数据框中,然后将apply
unique/do.call
排列到此数据框的每一列。 (我稍微修改了你的数据,所以'a'和'b'联合的长度不同,以确保它正常工作。)
lst <- list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:10, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12), .Names = c("a", "b")))
> apply(do.call(rbind, lst),2, function( x ) unique( do.call( c, x)))
$a
[1] 1 2 3 4 5 6 7 8 9 10 12
$b
[1] 6 7 8 9 10 11 1 2 3 4 5 12
答案 3 :(得分:1)
您的数据
df <- list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12), .Names = c("a", "b")))
这为您提供了嵌套列表的唯一值:
library(plyr)
df.l <- llply(df, function(x) unlist(unique(x)))
R> df.l
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10 11
[[2]]
[1] 6 7 8 9 10 11 1 2 3 4 5
[[3]]
[1] 12
修改强>
感谢Ramnath我改变了一些代码并希望这个答案符合你的问题的需要。为了说明,我也保留了以前的答案。稍微改变的数据现在有一个额外的列表。
df <- list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12, c = 10:14), .Names = c("a", "b", "c")))
f.x <- function(x.list) {
x.names <- names(x.list)
i <- combn(x.names, 2)
l <- apply(i, 2, function(y) x.list[y])
llply(l, unlist)
}
现在您可以将该功能应用于您的数据。
all.l <- llply(df, f.x)
llply(all.l, function(x) llply(x, unique))
R> [[1]]
[[1]][[1]]
[1] 1 2 3 4 5 6 7 8 9 10 11
[[2]]
[[2]][[1]]
[1] 6 7 8 9 10 11 1 2 3 4 5
[[3]]
[[3]][[1]]
[1] 12
[[3]][[2]]
[1] 12 10 11 13 14
[[3]][[3]]
[1] 12 10 11 13 14
但是,嵌套结构不是非常用户友好。这可能会有所改变......
答案 4 :(得分:0)
根据文件&#34;取消列出&#34;是一个递归函数,因此无论提供的列表的嵌套级别如何,您都可以通过将它们传递给unlist来获取所有元素。您可以按如下方式获取子列表的并集。
lst <- list(structure(list(a = 1:5, b = 6:11), .Names = c("a", "b")),
structure(list(a = 6:11, b = 1:5), .Names = c("a", "b")),
structure(list(a = 12, b = 12), .Names = c("a", "b")))
lapply(lst, function(sublst) unique(unlist(sublst)))
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10 11
[[2]]
[1] 6 7 8 9 10 11 1 2 3 4 5
[[3]]
[1] 12