获取其他向量中矢量元素的重复实例的索引(都非常大)

时间:2016-06-19 14:17:47

标签: r indexing

我有两个向量,一个(A)有大约1亿个非独特元素(整数),另一个(B)有100万个相同的,唯一的元素。我正在尝试获取一个列表,其中包含A中每个B元素的重复实例的索引。

A <- c(2, 1, 1, 1, 2, 1, 1, 3, 3, 2)
B <- 1:3

# would result in this:
[[1]]
[1] 2 3 4 6 7

[[2]]
[1]  1  5 10

[[3]]
[1] 8 9

我首先天真地尝试了这个:

b_indices <- lapply(B, function(b) which(A == b))

这是非常低效的,显然在几年内不会完成。

我尝试的第二件事是创建一个空向量列表,用B的所有元素索引,然后循环通过A,将索引附加到A中每个元素的相应向量。虽然技术上是O(n) ,我不确定重复追加元素的时间。这种方法显然需要2-3天,这仍然太慢......

有什么可以更快地运作吗?

3 个答案:

答案 0 :(得分:8)

这很快:

A1 <- order(A, method = "radix")

split(A1, A[A1])
#$`1`
#[1] 2 3 4 6 7
#
#$`2`
#[1]  1  5 10
#
#$`3`
#[1] 8 9

B <- seq_len(1e6)
set.seed(42)
A <- sample(B, 1e8, TRUE)

system.time({
  A1 <- order(A, method = "radix")

  res <- split(A1, A[A1])
})
# user      system     elapsed 
#8.650       1.056       9.704

答案 1 :(得分:6)

data.table可以说是处理R中大数据的最有效方式,它甚至可以让你避免一起使用那个100万个长度的数据!

require(data.table)
a <- data.table(x=rep(c("a","b","c"),each=3))
a[ , list( yidx = list(.I) ) , by = x ]

   a  yidx
1: a 1,2,3
2: b 4,5,6
3: c 7,8,9

使用您的示例数据:

a <- data.table(x=c(2, 1, 1, 1, 2, 1, 1, 3, 3, 2))
a[ , list( yidx = list(.I) ) , by = x ]

   a      yidx
1: 2   1, 5,10
2: 1 2,3,4,6,7
3: 3       8,9

将此添加到您的基准测试中。我敢说它应该比使用内置函数快得多,如果你大规模测试它。数据越大,data.table在我的经验中的相对表现就越好。

在我的基准中,我的Debian笔记本电脑上的order只需要大约46%,而在我的Windows笔记本电脑上只需{5>只有order ,具有8GB RAM和2.x GHz CPU。

B <- seq_len(1e6)
set.seed(42)
A <- data.table(x = sample(B, 1e8, TRUE))
system.time({
+   res <- A[ , list( yidx = list(.I) ) , by = x ]
+ })
   user  system elapsed 
   4.25    0.22    4.50 

答案 2 :(得分:2)

我们也可以使用dplyr

library(dplyr)
data_frame(A) %>% 
      mutate(B = row_number()) %>%
      group_by(A) %>%
      summarise(B = list(B)) %>% 
      .$B

#[[1]]
#[1] 2 3 4 6 7

#[[2]]
#[1]  1  5 10

#[[3]]
#[1] 8 9

在1e5大小的较小数据集中,它提供system.time

#   user  system elapsed 
#   0.01    0.00    0.02 

但是如其他帖子中所示的更大的例子,它更慢。但是,这是dplyr ...