我想创建一个函数来计算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))
答案 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