【问题标题】:Multiply many columns by a specific other column in R with data.table?用data.table将R中的特定其他列乘以许多列?
【发布时间】:2015-03-23 06:30:08
【问题描述】:

我在 R 中有一个大型 data.table,其中有几列带有美元值。在另一列中,我有一个通货膨胀调整数。我试图弄清楚如何用它乘以通货膨胀调整列来更新我的每个货币列。假设我有数据:

   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] 
}

返回

[1] "inc1"
 Error in get(var) : object 'inc1' not found 

我意识到这可能是一个直截了当的问题,我尝试在这里搜索其他问题以及各种在线指南和教程,但我找不到与我的具体问题匹配的示例。它类似于question,但不完全一样。

感谢您的帮助!

【问题讨论】:

  • 仅供现在查看此内容的任何人参考,我猜DT[, inc_cols := lapply(.SD,function(x)= x * deflator),.SDcols = inc_cols] 在提出这个问题时不起作用,但它适用于当前版本的data.table

标签: r data.table


【解决方案1】:

你可以试试

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)) 

【讨论】:

  • for-loop 与set() 一起使用会很棒,因为它避免了[.data.table 开销。
  • @Arun 谢谢,不确定这是否是您的意思。 for(i in 3:5){ set(DT, i=NULL, j=i, value=DT[[i]]*DT[['deflator']]) }
  • 正是我的意思!完美。
  • 谢谢,效果很好! data.table 很棒,但语法很棘手,感谢您的帮助。
  • 如果您还想按另一个变量分组,这可能吗?
【解决方案2】:

由于您可以在 data.tables 上使用 dplyr,您也可以这样做:

library(dplyr)
DT %>% mutate_each(funs(.*deflator), starts_with("inc"))

这会将 DT 中以“inc”开头的每一列乘以“deflator”列。

【讨论】:

  • 这也有效,谢谢。我继续向第一个帖子授予支票,因为它解决了我已经采取的问题,但我也感谢您的帮助。
  • mutate_each() 现在已弃用,取而代之的是 mutate_at()。代码现在可以写成DT %&gt;% mutate_at(vars(starts_with("inc")), ~.*deflator)
  • 现在使用 dplyr 1.0 类似的东西是 de rigeurDT %&gt;% mutate(across(starts_with("inc"),~.*deflator)
  • 也许在逗号之前需要第二个右括号?
【解决方案3】:

这种方法也很方便,但可能比使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    相关资源
    最近更新 更多