计算 r 中每行跨列的移动差异

Calculating moving differences across columns per row in r

我想按行对数据中的列进行计算。计算是“移动的”,因为我想知道第 1 列和第 2 列中两个数字之间的差异,然后是第 3 列和第 4 列,依此类推。我看过“loops”和“rollapply”函数,但无法弄清楚。以下是尝试的三个选项。只有第三个选项给了我我想要的结果,但它是非常冗长的代码并且也不允许自动化(输入数据将是一个更大的矩阵,因此为每一行输入计算将不起作用)。 请建议如何缩短此代码 and/or 任何其他 packages/functions 以检查哪个可以完成这项工作。谢谢!

我在 R 中的测试脚本 + errors/results

示例数据集

 a<- c(1,2,3, 4, 5)
 b<- c(1,2,3, 4, 5)
 c<- c(1,2,3, 4, 5)
 test.data <- data.frame(cbind(a,b*2,c*10))
 names(test.data) <- c("a", "b", "c")

尝试的计算示例:

选项 1

require(zoo)
rollapply(test.data, 2, diff, fill = NA, align = "right", by.column=FALSE)

RESULT 1(不是我们想要的。我们需要的是选项 3 的底部)

#     a  b  c
#[1,] NA NA NA
#[2,]  1  2 10
#[3,]  1  2 10
#[4,]  1  2 10
#[5,]  1  2 10

选项 2:

results <- for (i in 1:length(nrow(test.data))) {
diff(as.numeric(test.data[i,]), lag=1)
print(results)}

结果 2:(同样不是我们想要的)

# NULL

选项 3:可行,但还有很长的路要走,因此我想简化代码并使我的数据框中的任意长度的观察值和任意数量的列(即超过 3 列)通用。如果知道观察次数(即行数),我想“自动化”以下步骤。

row1=diff(as.numeric(test[1,], lag=1))
row2=diff(as.numeric(test[2,], lag=1))
row3=diff(as.numeric(test[3,], lag=1))
row4=diff(as.numeric(test[4,], lag=1))
row5=diff(as.numeric(test[5,], lag=1))

results.OK=cbind.data.frame(row1, row2, row3, row4, row5)
transpose.results.OK=data.frame(t(as.matrix(results.OK)))
names(transpose.results.OK)=c("diff.ab", "diff.bc")
Final.data = transpose.results.OK
print(Final.data)

结果 3:(这是我想要得到的结果,“row1”可以是“obs1”等)

#     diff.ab diff.bc
#row1       1       8
#row2       2      16
#row3       3      24
#row4       4      32
#row5       5      40

结束

这是重做的 3 个选项加上第 4 个选项:

# 1
library(zoo)
d <- t(rollapplyr(t(test.data), 2, diff, by.column = FALSE))

# 2
d <- test.data[-1]
for (i in 1:nrow(test.data)) d[i, ] <- diff(unlist(test.data[i, ]))

# 3
d <- t(diff(t(test.data)))

# 4 - also this works
nc <- ncol(test.data)
d <- test.data[-1] - test.data[-nc]

为他们中的任何一个设置名称:

colnames(d) <- paste0("diff.", head(names(test.data), -1), colnames(d))

(2)和(4)给出这个data.frame并且(1)和(3)给出相应的矩阵:

> d
  diff.ab diff.bc
1       1       8
2       2      16
3       3      24
4       4      32
5       5      40

如果需要另一个,请使用 as.matrixas.data.frame

一个基于 apply 的解决方案使用 diff 可以实现为:

# Result
res <- t(apply(test.data, 1, diff)) #One can change it to data.frame

# Name of the columns
colnames(res) <-  paste0("diff.", head(names(test.data), -1),
                               tail(names(test.data), -1))

res
#      diff.ab diff.bc
# [1,]       1       8
# [2,]       2      16
# [3,]       3      24
# [4,]       4      32
# [5,]       5      40