【问题标题】:The data.table package syntax: parentheses, .SD and .SDcolsdata.table 包语法:括号、.SD 和 .SDcols
【发布时间】:2019-02-05 16:02:53
【问题描述】:

我是 R 新手,我正在尝试理解这一行的语法。我明白它在做什么,但我不明白它是如何表达的:

plms[, (cols) := lapply(.SD, str_trim), .SDcols = cols]

plms 是一个数据表。 colsplms 中所有字符列的名称列表。此行将str_trim 应用于plms 中的所有字符列。但是,我不明白:

1) 为什么(cols) 存在于括号中。

2) .SD.SDcols 是什么意思。 .SD.SDcols 都没有在脚本中使用过 - 它们都在这里首先提到。前缀点的意义是什么?

我也有点不确定 := 运算符 - 我认为它在 data.tables 中具有扩展含义。

提前致谢!

【问题讨论】:

标签: r syntax data.table


【解决方案1】:

1) 在 R 中,() 是一个函数,可以被覆盖,即您可以为其分配不同的行为。当您执行(a <- 1) 时,您可能会注意到控制台正在打印1,即可以重新制作此行为。在data.table 的上下文中,您的示例请参见下文。

首先我们准备plms数据表:

set.seed(123)
plms <- data.table(
  a = sample(c("A", "B ", "C ", " D "), 5, replace = TRUE),
  b = sample(c("A", "B  ", "C ", " D "), 5, replace = TRUE),
  c = sample(c("A", "B ", "C ", " D "), 5, replace = TRUE)
)
cols <- c("a", "b", "c")
plms
#     a   b   c
# 1:  B    A  D 
# 2:  D   C   B 
# 3:  B   D   C 
# 4:  D   C   C 
# 5:  D  B     A

如您所见,生成的数据表带有尾随空格。然后让我们应用您的代码:

plms[, (cols) := lapply(.SD, str_trim), .SDcols = cols]
plms
# a b c
# 1: B A D
# 2: D C B
# 3: B D C
# 4: D C C
# 5: D B A

已删除尾随空格 - 好的。这意味着data.table 重新定义了() 的功能——它从cols 向量中获取列名,并将column-wisestrtrim 结果分配给这些列。

现在没有括号:

plms[, cols := lapply(.SD, str_trim), .SDcols = cols]
plms
# a   b   c      cols
# 1:  B    A  D  B,D,B,D,D
# 2:  D   C   B  A,C,D,C,B
# 3:  B   D   C  D,B,C,C,A
# 4:  D   C   C  B,D,B,D,D
# 5:  D  B     A A,C,D,C,B

实际上,这意味着您创建了列cols,并为该列分配了list

2) .SD - 是一个内部只读符号(实际上是data.table 对象)

.SD 是一个 data.table,其中包含每个组的 x 数据的子集,不包括 by(或 keyby)中使用的任何列。

您可以查看以下数据:

plms[, lapply(.SD, print), .SDcols = cols]
# [1] "B "  " D " "B "  " D " " D "
# [1] "A"   "C "  " D " "C "  "B  "
# [1] " D " "B "  "C "  "C "  "A"  
# a   b   c
# 1:  B    A  D 
# 2:  D   C   B 
# 3:  B   D   C 
# 4:  D   C   C 
# 5:  D  B     A

如您所见,将print 按列应用于.SD 的结果显示了SDcols 的选定列。

[] 也被重新定义,该函数的参数之一是.SDcols,用于为.SD 数据表选择列。请参阅下面的文档。

.SDcols 指定 x 的列要包含在特殊的 符号 .SD 代表 data.table 的子集。可能是性格 列名或数字位置。这对速度很有用 通过(可能非常多)列的子集应用函数; 例如,DT[, lapply(.SD, sum), by="x,y", .SDcols=301:350]。

3) := 也是一个函数(你可以通过?":=" 看到它的帮助。这个函数的主要思想是在对象内部修改数据(通过引用):

plms[, a := "x"]
plms
#    a   b   c
# 1: x   A  C 
# 2: x  D   B 
# 3: x   A  B 
# 4: x B    D 
# 5: x  C   B 

通常 R 按值工作,并且在函数执行期间不会修改对象(函数方法:函数在执行期间不应更改参数)。

从根本上说,这是data.table 包的争议点,因为对象内部状态的更改可能导致难以识别错误和调试困难,但与例如base::data.frame.

【讨论】:

    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 2013-05-12
    • 2022-01-08
    • 1970-01-01
    • 2016-10-13
    相关资源
    最近更新 更多