找到差异最有效的方法?

时间:2013-07-16 21:26:24

标签: r loops array-difference

非常简单的问题,我很遗憾不得不问这个问题。我希望有一个创造性思维能有比我想象的更好的解决方案。

我想找到矩阵的相邻值之间的差异,其中“type”的值相同。对于下面的例子,我想要一个值为2,6,1。

的向量
mat
     value type
[1,]  5   A
[2,]  7   A
[3,]  1   B
[4,]  2   C
[5,]  8   C
[6,]  9   C

我尝试过以两种方式实现它,但它们都很慢:

  • 方法1:如果type(row 1) = type(row 2),则查找value(row 2) - value(row 1),然后递增1。如果type(row 1) != type(row 2),则增加2。

  • 方法2:遍历每个不同的type并找出所有差异。

大约有500,000种不同的“类型”和500万种不同的行。谁能想到更有效的方式?我正在使用语言R进行编程,其中已经有一个函数可以找到我的差异(参见:?diff)。

2 个答案:

答案 0 :(得分:2)

由于您说有太多行要执行此操作,因此我建议使用data.table解决方案:

require(data.table)
DT <- data.table(df) # where `df` is your data.frame

DT[, diff(value), by=type]$V1
# [1] 2 6 1

在维度数据上模拟此代码:

您的尺寸数据需要近20秒(瓶塞应该是diff)。

require(data.table)
set.seed(45)
types <- sapply(1:5e5, function(x) paste0(sample(letters, 5, TRUE), collapse=""))

DT <- data.table(value=sample(100, 5e6, TRUE), type=sample(types, 5e6, TRUE))
system.time(t1 <- DT[, diff(value), by=type]$V1)
#   user  system elapsed 
# 18.610   0.238  19.166 

tapply的其他答案进行比较:

system.time(t2 <- tapply(DT[["value"]], DT[["type"]], diff))
#   user  system elapsed 
# 48.471   0.664  51.673 

另外,tapplytype对结果进行排序,而data.table key不保留原始订单。


编辑:关注@ eddi的评论:

> system.time(t3 <- DT[, value[-1]-value[-.N], by=type]$V1)
#  user  system elapsed 
# 6.221   0.195   6.641 

通过删除对diff的调用,可以提高3倍。谢谢@eddi。

答案 1 :(得分:0)

尝试:

tapply(mat[["value"]], mat[["type"]], diff)

然后你可以unlist你的结果以更整洁的格式获得它。