从列表中查找唯一值

时间:2010-10-07 07:26:51

标签: list r unique

假设您有一个值列表

x <- list(a=c(1,2,3), b = c(2,3,4), c=c(4,5,6))

我想从所有列表元素中找到唯一值。到目前为止,以下代码完成了这个技巧

unique(unlist(x))

有谁知道更有效的方式?我有一个包含很多价值的大量清单,并且非常感谢任何加速。

1 个答案:

答案 0 :(得分:41)

Marek建议的这个解决方案是对原始Q的最佳答案。请参阅下面的讨论其他方法以及为什么Marek最有用。

> unique(unlist(x, use.names = FALSE))
[1] 1 2 3 4 5 6

讨论

更快的解决方案是首先在unique()的组件上计算x,然后对这些结果进行最终unique()。这仅在列表的组件具有相同数量的唯一值时才有效,如下面两个示例中所示。 E.g:

首先是你的版本,然后我的双重独特方法:

> unique(unlist(x))
[1] 1 2 3 4 5 6
> unique.default(sapply(x, unique))
[1] 1 2 3 4 5 6

我们必须致电unique.default,因为[{1}} matrix方法可以保留一个保证金;这很好,因为矩阵可以被视为一个向量。

Marek在对此答案的评论中指出,unique方法的速度较慢可能是由于列表中的unlist。 Marek的解决方案是使用names use.names的{​​{1}}参数,如果使用的话,它会产生比上面的双唯一版本更快的解决方案。对于Roman的帖子的简单unlist,我们得到了

x

即使组件之间的独特元素数量不同,Marek的解决方案仍然有效。

这是一个更大的例子,包含所有三种方法的一些时间:

> unique(unlist(x, use.names = FALSE))
[1] 1 2 3 4 5 6

以下是使用## Create a large list (1000 components of length 100 each) DF <- as.list(data.frame(matrix(sample(1:10, 1000*1000, replace = TRUE), ncol = 1000))) 的两种方法的结果:

DF

这表明双> ## Do the three approaches give the same result: > all.equal(unique.default(sapply(DF, unique)), unique(unlist(DF))) [1] TRUE > all.equal(unique(unlist(DF, use.names = FALSE)), unique(unlist(DF))) [1] TRUE > ## Timing Roman's original: > system.time(replicate(10, unique(unlist(DF)))) user system elapsed 12.884 0.077 12.966 > ## Timing double unique version: > system.time(replicate(10, unique.default(sapply(DF, unique)))) user system elapsed 0.648 0.000 0.653 > ## timing of Marek's solution: > system.time(replicate(10, unique(unlist(DF, use.names = FALSE)))) user system elapsed 0.510 0.000 0.512 unique应用于单个组件然后unique()那些较小的唯一值组会快得多,但这种加速纯粹是由于到列表unique()上的names。如果我们告诉DF不使用unlist,则Marek的解决方案比此问题的双names快一点。由于Marek的解决方案正确使用了正确的工具,并且比解决方案更快,因此它是首选解决方案。

使用双unique方法的重要问题是,只有 if ,就像在这里的两个示例中一样,输入列表的每个组件(uniqueDF)具有相同数量的唯一值。在这种情况下,x会将结果简化为矩阵,以便我们应用sapply。如果输入列表的组件具有不同数量的唯一值,则双唯一解决方案将失败。