gpt4 book ai didi

r - 以不同方式使用数字索引对 data.table 列进行子集化时的不同结果

转载 作者:行者123 更新时间:2023-12-04 12:37:14 25 4
gpt4 key购买 nike

请参阅最小示例:

library(data.table)
DT <- data.table(x = 2, y = 3, z = 4)

DT[, c(1:2)] # first way
# x y
# 1: 2 3

DT[, (1:2)] # second way
# [1] 1 2

DT[, 1:2] # third way
# x y
# 1: 2 3

如本 post 中所述,现在可以使用数字索引对列进行子集化。但是,我想知道为什么索引被评估为 中的向量。第二种方式而不是列索引?

另外,我更新了 data.table现在:
> sessionInfo()
R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.4 LTS

Matrix products: default
BLAS: /usr/lib/atlas-base/atlas/libblas.so.3.0
LAPACK: /usr/lib/atlas-base/atlas/liblapack.so.3.0

locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] data.table_1.11.2

loaded via a namespace (and not attached):
[1] compiler_3.4.4 tools_3.4.4 yaml_2.1.17

最佳答案

通过查看 source code我们可以模拟不同输入的 data.tables 行为

if (!missing(j)) {
jsub = replace_dot_alias(substitute(j))
root = if (is.call(jsub)) as.character(jsub[[1L]])[1L] else ""
if (root == ":" ||
(root %chin% c("-","!") && is.call(jsub[[2L]]) && jsub[[2L]][[1L]]=="(" && is.call(jsub[[2L]][[2L]]) && jsub[[2L]][[2L]][[1L]]==":") ||
( (!length(av<-all.vars(jsub)) || all(substring(av,1L,2L)=="..")) &&
root %chin% c("","c","paste","paste0","-","!") &&
missing(by) )) { # test 763. TODO: likely that !missing(by) iff with==TRUE (so, with can be removed)
# When no variable names (i.e. symbols) occur in j, scope doesn't matter because there are no symbols to find.
# If variable names do occur, but they are all prefixed with .., then that means look up in calling scope.
# Automatically set with=FALSE in this case so that DT[,1], DT[,2:3], DT[,"someCol"] and DT[,c("colB","colD")]
# work as expected. As before, a vector will never be returned, but a single column data.table
# for type consistency with >1 cases. To return a single vector use DT[["someCol"]] or DT[[3]].
# The root==":" is to allow DT[,colC:colH] even though that contains two variable names.
# root == "-" or "!" is for tests 1504.11 and 1504.13 (a : with a ! or - modifier root)
# We don't want to evaluate j at all in making this decision because i) evaluating could itself
# increment some variable and not intended to be evaluated a 2nd time later on and ii) we don't
# want decisions like this to depend on the data or vector lengths since that can introduce
# inconistency reminiscent of drop=TRUE in [.data.frame that we seek to avoid.
with=FALSE

基本上, "[.data.table"捕获传递给 j 的表达式并根据一些预定义的规则决定如何对待它。如果满足其中一条规则,则设置 with=FALSE这基本上意味着列名被传递给 j ,使用标准评估。

规则(大致)如下:
  • 套装with=FALSE ,

    1.1.如果 j表达式是一个调用,调用是 :或者

    1.2.如果调用是 c("-","!") 的组合和 (:或者

    1.3.如果某个值(字符、整数、数字等)或 ..已传递给 j电话在 c("","c","paste","paste0","-","!")并且没有 by调用

  • 否则设置 with=TRUE
    所以我们可以把它转换成一个函数,看看是否满足任何条件(我跳过了将 . 转换为 list 函数,因为它在这里无关紧要。我们将直接用 list 测试)
    is_satisfied <- function(...) {
    jsub <- substitute(...)
    root = if (is.call(jsub)) as.character(jsub[[1L]])[1L] else ""
    if (root == ":" ||
    (root %chin% c("-","!") &&
    is.call(jsub[[2L]]) &&
    jsub[[2L]][[1L]]=="(" &&
    is.call(jsub[[2L]][[2L]]) &&
    jsub[[2L]][[2L]][[1L]]==":") ||
    ( (!length(av<-all.vars(jsub)) || all(substring(av,1L,2L)=="..")) &&
    root %chin% c("","c","paste","paste0","-","!"))) TRUE else FALSE
    }

    is_satisfied("x")
    # [1] TRUE
    is_satisfied(c("x", "y"))
    # [1] TRUE
    is_satisfied(..x)
    # [1] TRUE
    is_satisfied(1:2)
    # [1] TRUE
    is_satisfied(c(1:2))
    # [1] TRUE
    is_satisfied((1:2))
    # [1] FALSE
    is_satisfied(y)
    # [1] FALSE
    is_satisfied(list(x, y))
    # [1] FALSE

    关于r - 以不同方式使用数字索引对 data.table 列进行子集化时的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50314124/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com