如何在 data.frame 中动态创建差异列或增量列?
How do you dynamically create difference- or delta- columns in a data.frame?
我的 dataframe
有来自 Balance
、Balance1
、Balance2
、...、Balance36
.[=20= 的未结余额列名]
我想为每个月之间的增量添加一列,即 Delta2
= Balance2
- Balance1
如何通过下面的方法简化。
dataset$delta1 = apply(dataset[, c("Balance1","Balance")], 1, function(x){x[2]-x[1]})
dataset$delta2 = apply(dataset[, c("Balance2","Balance1")], 1, function(x){x[2]-x[1]})
...
dataset$delta35 = apply(dataset[, c("Balance35","Balance34")], 1, function(x){x[2]-x[1]})
dataset$delta36 = apply(dataset[, c("Balance36","Balance35")], 1, function(x){x[2]-x[1]})
归结为单行。首先,给你的数据集起一个简短的名字,df
是通常的名字。然后,使用直接减法;零需要调用 apply()
从一列中减去另一列:
df$delta1 <- df[,"Balance1"] - df[,"Balance"]
df$delta2 <- df[,"Balance2"] - df[,"Balance1"]
...
df$delta35 <- df[,"Balance35"] - df[,"Balance34")]
df$delta36 <- df[,"Balance36"] - df[,"Balance35")]
但由于整个计算具有规则结构,我们实际上只是在谈论生成一个 Nx36 差值数组,因此请使用数字列索引。假设您的 "Balance*" 列索引是 (50:85) 而您的 delta_cols 是 100:135 或其他任何内容。那么 "Balance*" 减法的 LHS 索引是 balance_lhs <- (50:84)
,RHS 索引是 (51:85)
,或者只是 ((50:84)+1)
(请记住,大多数运算符喜欢 R 中的加法矢量化)
所以你的 Nx36 阵列可以只用一行代码生成:
df[,delta_cols] <- df[,(balance_lhs+1)] - df[,balance_lhs]
并且您可以通过编程方式计算 delta_cols <- which(colnames(df) == c("delta1",...,"delta36")
,以避免代码中出现幻数列索引。
使用lapply
计算一行中所有 36 次比较的增量。
# Sample data (37 columns, labelled Balance, Balance1, ...)
set.seed(2017);
df <- as.data.frame(matrix(runif(37 * 100), ncol = 37));
colnames(df) <- paste("Balance", c("", seq(1:36)), sep = "");
# List of difference vectors (36 distance vectors, labelled delta1, ...)
lst <- lapply(2:ncol(df), function(i) df[, i] - df[, i - 1]);
names(lst) <- paste("delta", seq(1:36), sep = "");
# Combine with original dataframe
df <- cbind.data.frame(
df,
as.data.frame(lst));
我的 dataframe
有来自 Balance
、Balance1
、Balance2
、...、Balance36
.[=20= 的未结余额列名]
我想为每个月之间的增量添加一列,即 Delta2
= Balance2
- Balance1
如何通过下面的方法简化。
dataset$delta1 = apply(dataset[, c("Balance1","Balance")], 1, function(x){x[2]-x[1]})
dataset$delta2 = apply(dataset[, c("Balance2","Balance1")], 1, function(x){x[2]-x[1]})
...
dataset$delta35 = apply(dataset[, c("Balance35","Balance34")], 1, function(x){x[2]-x[1]})
dataset$delta36 = apply(dataset[, c("Balance36","Balance35")], 1, function(x){x[2]-x[1]})
归结为单行。首先,给你的数据集起一个简短的名字,df
是通常的名字。然后,使用直接减法;零需要调用 apply()
从一列中减去另一列:
df$delta1 <- df[,"Balance1"] - df[,"Balance"]
df$delta2 <- df[,"Balance2"] - df[,"Balance1"]
...
df$delta35 <- df[,"Balance35"] - df[,"Balance34")]
df$delta36 <- df[,"Balance36"] - df[,"Balance35")]
但由于整个计算具有规则结构,我们实际上只是在谈论生成一个 Nx36 差值数组,因此请使用数字列索引。假设您的 "Balance*" 列索引是 (50:85) 而您的 delta_cols 是 100:135 或其他任何内容。那么 "Balance*" 减法的 LHS 索引是 balance_lhs <- (50:84)
,RHS 索引是 (51:85)
,或者只是 ((50:84)+1)
(请记住,大多数运算符喜欢 R 中的加法矢量化)
所以你的 Nx36 阵列可以只用一行代码生成:
df[,delta_cols] <- df[,(balance_lhs+1)] - df[,balance_lhs]
并且您可以通过编程方式计算 delta_cols <- which(colnames(df) == c("delta1",...,"delta36")
,以避免代码中出现幻数列索引。
使用lapply
计算一行中所有 36 次比较的增量。
# Sample data (37 columns, labelled Balance, Balance1, ...)
set.seed(2017);
df <- as.data.frame(matrix(runif(37 * 100), ncol = 37));
colnames(df) <- paste("Balance", c("", seq(1:36)), sep = "");
# List of difference vectors (36 distance vectors, labelled delta1, ...)
lst <- lapply(2:ncol(df), function(i) df[, i] - df[, i - 1]);
names(lst) <- paste("delta", seq(1:36), sep = "");
# Combine with original dataframe
df <- cbind.data.frame(
df,
as.data.frame(lst));