用 data.table 将许多列乘以 R 中的特定其他列?
Multiply many columns by a specific other column in R with data.table?
我在 R 中有一个很大的 data.table,其中有几列带有美元值。在另一列中,我有一个 inflation 调整编号。我想弄清楚如何用它乘以 inflation 调整列来更新我的每个货币列。假设我有数据:
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
给出输出:
id year inc1 inc2 inc3 deflator
1: 1 8 0.4754808 0.6678110 0.41533976 -0.64126988
2: 2 2 0.6568746 0.7765634 0.70616373 0.39687915
3: 3 6 0.8192947 0.9236281 0.90002534 -0.69545700
4: 4 4 0.7781929 0.1624902 0.17565790 0.05263055
5: 5 7 0.6232520 0.8024975 0.86449836 0.70781887
---
996: 996 2 0.9676383 0.2238746 0.19822000 0.78564836
997: 997 9 0.9877410 0.5783748 0.57497438 -1.63365223
998: 998 8 0.2220570 0.6500632 0.19814932 1.00260174
999: 999 3 0.4793767 0.2830457 0.54835581 1.04168818
1000: 1000 8 0.2003476 0.6121637 0.02921505 0.34933690
实际上我有 inc1
- inc100
,而不仅仅是三个变量,我想找出一种方法来执行此操作:
DT[, inc1 := inc1 * deflator]
我的 100 个收入列中的每一个(上面假数据中的 inc1、inc2、inc3)。我将来会有超过 100 列,所以我想找出一种方法来在列上循环操作。有没有办法一次对所有收入列执行此操作?
我想做这样的事情:
inc_cols = c(inc1, inc2, inc3)
DT[, inc_cols := lapply(inc_cols,function(x)= x * deflator),]
或
DT[, inc_cols := lapply(.SD,function(x)= x * deflator),.SDcols = inc_cols]
但这些似乎都不起作用。我还尝试使用 get()
函数来明确 deflator
是引用列,例如:
DT[, inc_cols := lapply(.SD,function(x)= x * get(deflator)),.SDcols = inc_cols]
但运气不佳。我还尝试使用以下内容遍历变量:
for (var in inc_cols) {
print(var)
DT[, get(var) := get(var) *infAdj2010_mult]
}
哪个returns
[1] "inc1"
Error in get(var) : object 'inc1' not found
我意识到这可能是一个直截了当的问题,我尝试在此处搜索其他问题以及各种在线指南和教程,但找不到与我的具体问题相匹配的示例。它类似于此 question,但不完全相同。
感谢您的帮助!
你可以试试
DT[, (inc_cols) := lapply(.SD, function(x)
x * DT[['deflator']] ), .SDcols = inc_cols]
head(DT1,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
或者如果你需要一个循环
for(inc in inc_cols){
nm1 <- as.symbol(inc)
DT[,(inc):= eval(nm1)*deflator]
}
head(DT,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
或者使用 set
的可能选项应该非常快,因为可以避免 [.data.table
的开销(@Arun 建议)
indx <- grep('inc', colnames(DT))
for(j in indx){
set(DT, i=NULL, j=j, value=DT[[j]]*DT[['deflator']])
}
head(DT,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
其中
inc_cols <- grep('^inc', colnames(DT), value=TRUE)
数据
set.seed(24)
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
由于您可以在 data.tables 上使用 dplyr,您还可以:
library(dplyr)
DT %>% mutate_each(funs(.*deflator), starts_with("inc"))
这会将以 "inc" 开头的 DT 的每一列乘以 "deflator" 列。
这种方法也很方便,但可能比使用 set()
慢:
library(data.table); library(magrittr)
set.seed(42)
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
vars <- names(DT) %>% .[grepl("inc", .)]
DT[, (vars) := .SD * deflator, .SDcols = vars]
DT[]
id year inc1 inc2 inc3 deflator
1: 1 9 0.212563676 0.24806366 0.06860638 0.2505781
2: 2 9 -0.017438715 -0.12186792 -0.26241497 -0.2779240
3: 3 3 -1.414016119 -1.20714809 -0.76920337 -1.7247357
4: 4 8 -1.082336969 -1.78411512 -1.08720698 -2.0067049
5: 5 6 -0.644638321 -1.07757416 -0.20895576 -1.2918083
---
996: 996 1 -0.573551720 -1.93996157 -0.50171303 -2.1569621
997: 997 5 -0.007899417 -0.01561619 -0.05708009 -0.0920275
998: 998 1 -0.090975121 -0.30475714 -0.27291825 -0.3974001
999: 999 5 -0.045984079 -0.01563942 -0.07868934 -0.1383273
1000: 1000 0 -0.785962308 -0.63266975 -0.29247974 -0.8257650
@IceCreamToucan 指出以下内容应该适用于较新版本的 DT。
DT[, inc_cols := lapply(.SD,function(x)= x * deflator),.SDcols = inc_cols]
对我来说,我必须对 LHS 执行以下操作才能使其正常工作。另外,请参阅 RHS 编辑。
DT[, c(inc_cols) := lapply(.SD, function(x) x * deflator), .SDcols = inc_cols]
-或-
DT[, (inc_cols) := lapply(.SD, function(x) x * deflator), .SDcols = inc_cols]
我在 R 中有一个很大的 data.table,其中有几列带有美元值。在另一列中,我有一个 inflation 调整编号。我想弄清楚如何用它乘以 inflation 调整列来更新我的每个货币列。假设我有数据:
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
给出输出:
id year inc1 inc2 inc3 deflator
1: 1 8 0.4754808 0.6678110 0.41533976 -0.64126988
2: 2 2 0.6568746 0.7765634 0.70616373 0.39687915
3: 3 6 0.8192947 0.9236281 0.90002534 -0.69545700
4: 4 4 0.7781929 0.1624902 0.17565790 0.05263055
5: 5 7 0.6232520 0.8024975 0.86449836 0.70781887
---
996: 996 2 0.9676383 0.2238746 0.19822000 0.78564836
997: 997 9 0.9877410 0.5783748 0.57497438 -1.63365223
998: 998 8 0.2220570 0.6500632 0.19814932 1.00260174
999: 999 3 0.4793767 0.2830457 0.54835581 1.04168818
1000: 1000 8 0.2003476 0.6121637 0.02921505 0.34933690
实际上我有 inc1
- inc100
,而不仅仅是三个变量,我想找出一种方法来执行此操作:
DT[, inc1 := inc1 * deflator]
我的 100 个收入列中的每一个(上面假数据中的 inc1、inc2、inc3)。我将来会有超过 100 列,所以我想找出一种方法来在列上循环操作。有没有办法一次对所有收入列执行此操作?
我想做这样的事情:
inc_cols = c(inc1, inc2, inc3)
DT[, inc_cols := lapply(inc_cols,function(x)= x * deflator),]
或
DT[, inc_cols := lapply(.SD,function(x)= x * deflator),.SDcols = inc_cols]
但这些似乎都不起作用。我还尝试使用 get()
函数来明确 deflator
是引用列,例如:
DT[, inc_cols := lapply(.SD,function(x)= x * get(deflator)),.SDcols = inc_cols]
但运气不佳。我还尝试使用以下内容遍历变量:
for (var in inc_cols) {
print(var)
DT[, get(var) := get(var) *infAdj2010_mult]
}
哪个returns
[1] "inc1"
Error in get(var) : object 'inc1' not found
我意识到这可能是一个直截了当的问题,我尝试在此处搜索其他问题以及各种在线指南和教程,但找不到与我的具体问题相匹配的示例。它类似于此 question,但不完全相同。
感谢您的帮助!
你可以试试
DT[, (inc_cols) := lapply(.SD, function(x)
x * DT[['deflator']] ), .SDcols = inc_cols]
head(DT1,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
或者如果你需要一个循环
for(inc in inc_cols){
nm1 <- as.symbol(inc)
DT[,(inc):= eval(nm1)*deflator]
}
head(DT,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
或者使用 set
的可能选项应该非常快,因为可以避免 [.data.table
的开销(@Arun 建议)
indx <- grep('inc', colnames(DT))
for(j in indx){
set(DT, i=NULL, j=j, value=DT[[j]]*DT[['deflator']])
}
head(DT,2)
# id year inc1 inc2 inc3 deflator
#1: 1 3 0.614838304 0.009796974 0.3236051 0.7735552
#2: 2 2 -0.001583579 -0.082289606 -0.1365115 -0.6644330
其中
inc_cols <- grep('^inc', colnames(DT), value=TRUE)
数据
set.seed(24)
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
由于您可以在 data.tables 上使用 dplyr,您还可以:
library(dplyr)
DT %>% mutate_each(funs(.*deflator), starts_with("inc"))
这会将以 "inc" 开头的 DT 的每一列乘以 "deflator" 列。
这种方法也很方便,但可能比使用 set()
慢:
library(data.table); library(magrittr)
set.seed(42)
DT <- data.table(id=1:1000,year=round(runif(1000)*10),
inc1 = runif(1000), inc2 = runif(1000), inc3 = runif(1000),
deflator = rnorm(1000))
vars <- names(DT) %>% .[grepl("inc", .)]
DT[, (vars) := .SD * deflator, .SDcols = vars]
DT[]
id year inc1 inc2 inc3 deflator
1: 1 9 0.212563676 0.24806366 0.06860638 0.2505781
2: 2 9 -0.017438715 -0.12186792 -0.26241497 -0.2779240
3: 3 3 -1.414016119 -1.20714809 -0.76920337 -1.7247357
4: 4 8 -1.082336969 -1.78411512 -1.08720698 -2.0067049
5: 5 6 -0.644638321 -1.07757416 -0.20895576 -1.2918083
---
996: 996 1 -0.573551720 -1.93996157 -0.50171303 -2.1569621
997: 997 5 -0.007899417 -0.01561619 -0.05708009 -0.0920275
998: 998 1 -0.090975121 -0.30475714 -0.27291825 -0.3974001
999: 999 5 -0.045984079 -0.01563942 -0.07868934 -0.1383273
1000: 1000 0 -0.785962308 -0.63266975 -0.29247974 -0.8257650
@IceCreamToucan 指出以下内容应该适用于较新版本的 DT。
DT[, inc_cols := lapply(.SD,function(x)= x * deflator),.SDcols = inc_cols]
对我来说,我必须对 LHS 执行以下操作才能使其正常工作。另外,请参阅 RHS 编辑。
DT[, c(inc_cols) := lapply(.SD, function(x) x * deflator), .SDcols = inc_cols]
-或-
DT[, (inc_cols) := lapply(.SD, function(x) x * deflator), .SDcols = inc_cols]