基于R中向量中每个列表的公共第一元素组合列表向量中的所有元素

时间:2016-01-21 07:55:12

标签: r list vector frequency frequency-analysis

我有一个相当大的列表向量(大约300,000行)。 例如,让我们考虑以下内容:

vec = c( 
  list(c("A",10,11,12)), 
  list(c("B",10,11,15)),
  list(c("A",10,12,12,16)),
  list(c("A",11,12,16,17)) )

现在,我想做以下事情:

对于向量中每个列表的每个唯一的第一个元素,我需要在向量的所有列表中出现与此对应的所有唯一元素以及相应的频率。

输出有点像:

对于A,我的元素10, 11 12, 16 & 17的频率分别为2,2,4,2 & 1。对于B10, 11, 15的频率为1,1,1

非常感谢, ANKUR。

1 个答案:

答案 0 :(得分:3)

这是一种方法。

首先,创建列表的简单方法是:

L <- list(c("A", 10, 11, 12), 
          c("B", 10, 11, 15), 
          c("A", 10, 12, 12, 16), 
          c("A", 11, 12, 16, 17))

现在你可以按第一个字符分割,然后将除第一个字符之外的所有字符制成表格。

tapply(L, sapply(L, '[[', 1), function(x) 
  table(unlist(lapply(x, function(x) x[-1]))))

## $A
## 
## 10 11 12 16 17 
##  2  2  4  2  1 
## 
## $B
## 
## 10 11 15 
##  1  1  1 

扩展到包含300,000个相似大小元素的列表:

L <- replicate(300000, c(sample(LETTERS, 1), sample(100, sample(3:4, 1))))

system.time(
  freqs <- tapply(L, sapply(L, '[[', 1), function(x) 
    table(unlist(lapply(x, function(x) x[-1]))))
)

## user  system elapsed 
## 0.68    0.00    0.69 

如果要根据下面的OP评论对结果列表的向量进行排序,您只需修改应用于L组的函数:

tapply(L, sapply(L, '[[', 1), function(x) 
  sort(table(unlist(lapply(x, function(x) x[-1]))), decreasing=TRUE))

## $A
## 
## 12 10 11 16 17 
##  4  2  2  2  1 
## 
## $B
## 
## 10 11 15 
##  1  1  1 

如果您只想将特定组的值制成表格,例如小组A(以A开头的向量),您可以将上述结果分组:

L2 <- tapply(L, sapply(L, '[[', 1), function(x) 
  sort(table(unlist(lapply(x, function(x) x[-1]))), decreasing=TRUE), 
  simplify=FALSE)

L2$A

(请注意,我添加了simplify=FALSE,这样即使各组中唯一元素的数量相同,这也会有效。)

仅对感兴趣的组执行操作更有效,但在这种情况下,可能以下情况更好:

sort(table(unlist(
  lapply(split(L, sapply(L, '[[', 1))$A, function(x) x[-1])
)), decreasing=TRUE)

其中split首先根据向量的第一个元素将L拆分为组,然后我们将A组合为$A