为了账号安全,请及时绑定邮箱和手机立即绑定

当变量名存储在字符向量中时,选择/赋值到data.table

当变量名存储在字符向量中时,选择/赋值到data.table

猛跑小猪 2019-06-26 13:22:20
当变量名存储在字符向量中时,选择/赋值到data.table如何引用data.table如果变量名存储在字符向量中?例如,这适用于data.frame:df <- data.frame(col1 = 1:3)colname <- "col1"df[colname] <- 4:6df#   col1# 1    4# 2    5# 3    6如何对data.table执行相同的操作?:=符号?最明显的是dt[ , list(colname)]不起作用(我也没料到)。
查看完整描述

3 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

两种编程方式选择变量:

  1. with = FALSE:

    DT = data.table(col1 = 1:3)colname = "col1"DT[, colname, with = FALSE] #    col1# 1:    1# 2:    2# 3:    3
  2. “点”(..)前缀:

    DT[, ..colname]    #    col1# 1:    1# 2:    2# 3:    3

关于“点”的进一步描述(..)符号,见1.10.2中的新特点(目前没有在帮助文本中描述)。

指派若要变量,请将:=括号内:

DT[, (colname) := 4:6]    #    col1# 1:    4# 2:    5# 3:    6

后者称为列。普朗克,因为您将整个列向量替换为引用。如果子集i在这里,它将以参考的方式签署。亲生(colname)是在2014年10月cran版1.9.4版中引入的速记。这是新闻项目:

使用with = FALSE带着:=现在所有情况下都不推荐使用,因为将lhs包装在:=使用括号已经有一段时间了。

colVar = "col1"DT[, colVar := 1, with = FALSE]                 # deprecated, still works silentlyDT[, (colVar) := 1]                             # please change to thisDT[, c("col1", "col2") := 1]                    # no changeDT[, 2:4 := 1]                                  # no changeDT[, c("col1","col2") := list(sum(a), mean(b)]  # no changeDT[, `:=`(...), by = ...]                       # no change

另见细节分节?`:=`:

DT[i, (colnamevector) := value]# [...] The parens are enough to stop the LHS being a symbol

为了在评论中回答更多的问题,这里有一个方法(和往常一样,有很多种方法):

DT[, colname := cumsum(get(colname)), with = FALSE]#    col1# 1:    4# 2:    9# 3:   15

或者,您可能会发现更容易读、写和调试eval a paste,类似于构造要发送到服务器的动态SQL语句:

expr = paste0("DT[,",colname,":=cumsum(",colname,")]")expr# [1] "DT[,col1:=cumsum(col1)]"eval(parse(text=expr))#    col1# 1:    4# 2:   13# 3:   28

如果经常这样做,就可以定义一个助手函数。EVAL :

EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))EVAL("DT[,",colname,":=cumsum(",colname,")]")#    col1# 1:    4# 2:   17# 3:   45

现在data.table1.8.2自动优化j为了提高效率,最好使用eval方法。这个get()在……里面j防止某些优化,例如。

或者,有set()..低开销,功能形式:=在这里会很好。看见?set.

set(DT, j = colname, value = cumsum(DT[[colname]]))DT#    col1# 1:    4# 2:   21# 3:   66


查看完整回答
反对 回复 2019-06-26
?
长风秋雁

TA贡献1757条经验 获得超7个赞

对于多列和应用于列值的函数。

在更新函数的值时,rhs必须是一个列表对象,因此使用.SD带着lapply会成功的。

下面的示例将整数列转换为数字列。

a1 <- data.table(a=1:5, b=6:10, c1=letters[1:5])sapply(a1, class)  # show classes of columns#         a           b          c1 # "integer"   "integer" "character" # column name character vectornm <- c("a", "b")# Convert columns a and b to numeric typea1[, j = (nm) := lapply(.SD, as.numeric ), .SDcols = nm ]sapply(a1, class)#         a           b          c1 # "numeric"   "numeric" "character"


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 531 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信