R中数据帧或矩阵的列之间的滞后-1差异

时间:2017-01-20 19:57:53

标签: r dataframe matrix difference

我想创建一个函数来计算R中多列之间的lag-1差异。

例如,我的数据框看起来像这样:

  id  Value  Value2 Value3 Value4  
A234     10     15     NA     NA 
B345     20     25     25     30 
C500     20     25     15     NA

我希望函数能够区分第5列和第4列。然后,第4和第3列,然后是第3和第2列。

我知道前两个Q&关于行之间的区别:

但我无法调整解决方案来处理列。对不起,如果这太简单了。我是R的新手。

df <- structure(list(id = c("A234", "B345", "C500"), Value = c(10L, 
20L, 20L), Value2 = c(15L, 25L, 25L), Value3 = c(NA, 25L, 15L
), Value4 = c(NA, 30L, NA)), .Names = c("id", "Value", "Value2", 
"Value3", "Value4"), class = "data.frame", row.names = c(NA, -3L))

3 个答案:

答案 0 :(得分:1)

数据框

  

我希望函数能够区分第5列和第4列。然后,第4和第3列,然后是第3和第2列。

我们可以做到

cbind(df[1], df[3:5] - df[2:4])
#    id Value2 Value3 Value4
#1 A234      5     NA     NA
#2 B345      5      0      5
#3 C500      5    -10     NA

df[3:5] - df[2:4]有效,因为在相同大小的两个数据帧之间的R中明确定义了元素运算。特别是,DF1 - DF2的列名将继承第一个数据框DF1的列名。

我们也可以使用否定索引:

df0 <- df[-1]  ## drop "id" column
cbind(df[1], df0[-1] - df0[-length(df0)])
#    id Value2 Value3 Value4
#1 A234      5     NA     NA
#2 B345      5      0      5
#3 C500      5    -10     NA

<强>警告:

由于数据帧可能会在不同的列中存储不同类型的数据,因此我建议您先尝试检查其列,然后再尝试取消差异,否则算术运算可能无效。使用示例数据框,我们可以

sapply(df, class)
#         id       Value      Value2      Value3      Value4 
#"character"   "integer"   "integer"   "integer"   "integer" 

因此,最后4列之间的差异是有效的。

以下是iris数据集的另一个示例:

sapply(iris, class)
#Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#   "numeric"    "numeric"    "numeric"    "numeric"     "factor" 

最后一列是“因子”,不能用于有效算术。

请注意,我们使用class而不是mode对每个数据框列进行类型检查,因为它会进行更全面的检查。有关详细说明,请参阅this Q & A

矩阵

矩阵只能容纳单一类型的数据。使用mode检查数据类型以确保算术有效。例如,您无法对“字符”数据进行算术运算。

假设我们有一个“数字”矩阵

set.seed(0)
A <- round(matrix(runif(25), 5, 5), 2)
#     [,1] [,2] [,3] [,4] [,5]
#[1,] 0.90 0.20 0.06 0.77 0.78
#[2,] 0.27 0.90 0.21 0.50 0.93
#[3,] 0.37 0.94 0.18 0.72 0.21
#[4,] 0.57 0.66 0.69 0.99 0.65
#[5,] 0.91 0.63 0.38 0.38 0.13

mode(A)
#[1] "numeric"

我们可以使用以下内容来区分第2列和第1列,第3列和第2列等:

A[, -1, drop = FALSE] - A[, -ncol(A), drop = FALSE]
#      [,1]  [,2] [,3]  [,4]
#[1,] -0.70 -0.14 0.71  0.01
#[2,]  0.63 -0.69 0.29  0.43
#[3,]  0.57 -0.76 0.54 -0.51
#[4,]  0.09  0.03 0.30 -0.34
#[5,] -0.28 -0.25 0.00 -0.25

答案 1 :(得分:0)

没有测试这个,但是,假设你的data.frame被称为df,它可以很简单 cbind(df$Value2-df$Value,df$Value3-df$Value2,df$Value4-df$Value3) 你可以非常轻松地说唱而不是功能。

答案 2 :(得分:0)

我认为,为了您的目的,李哲元的答案是最简单,最优雅的。但是,我只是想展示如何使用我的goto函数解决这个问题,以便从包diff中获得值Matrix之间的差异。在我的回答中,我保留了你要求的订单(第5栏 - 第4栏,第4栏 - 第3栏等)。

# Load package
library(Matrix)    

# Create a dataframe of differences
cbind(df[1], rev(as.data.frame(t(apply(df[-1], 1, diff, 1)))))
#    id Value4 Value3 Value2
#1 A234     NA     NA      5
#2 B345      5      0      5
#3 C500     NA    -10      5