非常简单的问题,我很遗憾不得不问这个问题。我希望有一个创造性思维能有比我想象的更好的解决方案。
我想找到矩阵的相邻值之间的差异,其中“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)。
答案 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
另外,tapply
按type
对结果进行排序,而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
你的结果以更整洁的格式获得它。