1

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

我想找到“类型”值相同的矩阵的相邻值之间的差异。对于下面的示例,我想要一个值为 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),然后加一。如果type(row 1) != type(row 2),则增加 2。

  • 方法 2:遍历每个不同之处type并找到所有不同之处。

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

4

2 回答 2

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 

此外,按where as withouttapply对结果进行排序将保留原始顺序。typedata.tablekey


编辑:遵循@eddi 的评论:

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

通过删除对diff. 谢谢@eddi。

于 2013-07-16T21:32:50.137 回答
0

尝试:

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

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

于 2013-07-16T21:29:42.590 回答