更改 data.table r 中的多个列
Changing multiple Columns in data.table r
我正在寻找一种在 R 中操作 data.table 中的多个列的方法。由于我必须动态处理列以及第二个输入,所以我找不到答案。
这个想法是通过将所有值除以日期值来索引某个日期的两个或多个系列,例如:
set.seed(132)
# simulate some data
dt <- data.table(date = seq(from = as.Date("2000-01-01"), by = "days", length.out = 10),
X1 = cumsum(rnorm(10)),
X2 = cumsum(rnorm(10)))
# set a date for the index
indexDate <- as.Date("2000-01-05")
# get the column names to be able to select the columns dynamically
cols <- colnames(dt)
cols <- cols[substr(cols, 1, 1) == "X"]
第 1 部分:简单数据。frame/apply 方法
df <- as.data.frame(dt)
# get the right rownumber for the indexDate
rownum <- max((1:nrow(df))*(df$date==indexDate))
# use apply to iterate over all columns
df[, cols] <- apply(df[, cols],
2,
function(x, i){x / x[i]}, i = rownum)
第 2 部分:(快速)data.table 方法
到目前为止,我的 data.table 方法如下所示:
for(nam in cols) {
div <- as.numeric(dt[rownum, nam, with = FALSE])
dt[ ,
nam := dt[,nam, with = FALSE] / div,
with=FALSE]
}
尤其是所有 with = FALSE
看起来都不像 data.table。
您知道执行此操作的任何 faster/more 优雅方法吗?
非常感谢任何想法!
一种选择是使用 set
,因为这涉及多个列。使用 set
的好处是它会避免 [.data.table
的开销并使其更快。
library(data.table)
for(j in cols){
set(dt, i=NULL, j=j, value= dt[[j]]/dt[[j]][rownum])
}
或者稍微慢一点的选项是
dt[, (cols) :=lapply(.SD, function(x) x/x[rownum]), .SDcols=cols]
根据您的代码和 akrun 给出的答案,我建议您使用 .SDcols
提取数字列并使用 lapply
循环遍历它们。以下是我的做法:
index <-as.Date("2000-01-05")
rownum<-max((dt$date==index)*(1:nrow(dt)))
dt[, lapply(.SD, function (i) i/i[rownum]), .SDcols = is.numeric]
如果您有大量数字列并且希望对所有列应用此除法,则使用 .SDcols 可能特别有用。
我正在寻找一种在 R 中操作 data.table 中的多个列的方法。由于我必须动态处理列以及第二个输入,所以我找不到答案。
这个想法是通过将所有值除以日期值来索引某个日期的两个或多个系列,例如:
set.seed(132)
# simulate some data
dt <- data.table(date = seq(from = as.Date("2000-01-01"), by = "days", length.out = 10),
X1 = cumsum(rnorm(10)),
X2 = cumsum(rnorm(10)))
# set a date for the index
indexDate <- as.Date("2000-01-05")
# get the column names to be able to select the columns dynamically
cols <- colnames(dt)
cols <- cols[substr(cols, 1, 1) == "X"]
第 1 部分:简单数据。frame/apply 方法
df <- as.data.frame(dt)
# get the right rownumber for the indexDate
rownum <- max((1:nrow(df))*(df$date==indexDate))
# use apply to iterate over all columns
df[, cols] <- apply(df[, cols],
2,
function(x, i){x / x[i]}, i = rownum)
第 2 部分:(快速)data.table 方法 到目前为止,我的 data.table 方法如下所示:
for(nam in cols) {
div <- as.numeric(dt[rownum, nam, with = FALSE])
dt[ ,
nam := dt[,nam, with = FALSE] / div,
with=FALSE]
}
尤其是所有 with = FALSE
看起来都不像 data.table。
您知道执行此操作的任何 faster/more 优雅方法吗?
非常感谢任何想法!
一种选择是使用 set
,因为这涉及多个列。使用 set
的好处是它会避免 [.data.table
的开销并使其更快。
library(data.table)
for(j in cols){
set(dt, i=NULL, j=j, value= dt[[j]]/dt[[j]][rownum])
}
或者稍微慢一点的选项是
dt[, (cols) :=lapply(.SD, function(x) x/x[rownum]), .SDcols=cols]
根据您的代码和 akrun 给出的答案,我建议您使用 .SDcols
提取数字列并使用 lapply
循环遍历它们。以下是我的做法:
index <-as.Date("2000-01-05")
rownum<-max((dt$date==index)*(1:nrow(dt)))
dt[, lapply(.SD, function (i) i/i[rownum]), .SDcols = is.numeric]
如果您有大量数字列并且希望对所有列应用此除法,则使用 .SDcols 可能特别有用。