Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 当变量名存储在字符向量中时,选择/分配给data.table_R_Data.table - Fatal编程技术网

R 当变量名存储在字符向量中时,选择/分配给data.table

R 当变量名存储在字符向量中时,选择/分配给data.table,r,data.table,R,Data.table,如果变量名存储在字符向量中,如何引用数据表中的变量?例如,这适用于data.frame: df <- data.frame(col1 = 1:3) colname <- "col1" df[colname] <- 4:6 df # col1 # 1 4 # 2 5 # 3 6 df以编程方式选择变量的两种方法: with=FALSE: DT = data.table(col1 = 1:3) colname = "col1" DT

如果变量名存储在字符向量中,如何引用
数据表中的变量?例如,这适用于
data.frame

df <- data.frame(col1 = 1:3)
colname <- "col1"
df[colname] <- 4:6
df
#   col1
# 1    4
# 2    5
# 3    6

df以编程方式选择变量的两种方法:

  • with=FALSE

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

  • 有关“dot-dot”(
    )表示法的进一步说明,请参阅(帮助文本中目前未对其进行说明)

    要分配给变量,请将
    :=
    的左括号括起来:

    DT[, (colname) := 4:6]    
    #    col1
    # 1:    4
    # 2:    5
    # 3:    6
    
    后者被称为列plonk,因为通过引用替换整个列向量。如果存在一个子集
    i
    ,它将通过引用进行子分配。
    (colname)
    是2014年10月1.9.4版中引入的缩写。这是:

    在所有情况下都不推荐使用
    with=FALSE
    with
    :=
    ,因为包装 带括号的
    :=
    的左半音一直是首选

    另请参见
    ?`:=`
    中的详细信息部分:

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

    为了回答评论中的进一步问题,这里有一种方法(通常有很多方法):

    或者,您可能会发现只需对
    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
    
    如果经常这样做,可以定义一个helper函数
    EVAL

    EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
    
    EVAL("DT[,",colname,":=cumsum(",colname,")]")
    #    col1
    # 1:    4
    # 2:   17
    # 3:   45
    
    既然
    data.table
    1.8.2自动优化了
    j
    的效率,那么最好使用
    eval
    方法。例如,
    j
    中的
    get()

    或者,有
    set()
    。一种低开销的函数形式
    :=
    ,在这里就可以了。请参见设置

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

    以编程方式选择变量的两种方法:

  • with=FALSE

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

  • 有关“dot-dot”(
    )表示法的进一步说明,请参阅(帮助文本中目前未对其进行说明)

    要分配给变量,请将
    :=
    的左括号括起来:

    DT[, (colname) := 4:6]    
    #    col1
    # 1:    4
    # 2:    5
    # 3:    6
    
    后者被称为列plonk,因为通过引用替换整个列向量。如果存在一个子集
    i
    ,它将通过引用进行子分配。
    (colname)
    是2014年10月1.9.4版中引入的缩写。这是:

    在所有情况下都不推荐使用
    with=FALSE
    with
    :=
    ,因为包装 带括号的
    :=
    的左半音一直是首选

    另请参见
    ?`:=`
    中的详细信息部分:

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

    为了回答评论中的进一步问题,这里有一种方法(通常有很多方法):

    或者,您可能会发现只需对
    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
    
    如果经常这样做,可以定义一个helper函数
    EVAL

    EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
    
    EVAL("DT[,",colname,":=cumsum(",colname,")]")
    #    col1
    # 1:    4
    # 2:   17
    # 3:   45
    
    既然
    data.table
    1.8.2自动优化了
    j
    的效率,那么最好使用
    eval
    方法。例如,
    j
    中的
    get()

    或者,有
    set()
    。一种低开销的函数形式
    :=
    ,在这里就可以了。请参见设置

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

    *这不是一个真正的答案,但我没有足够的街头信誉来发表评论:/

    无论如何,对于那些可能希望在数据表中使用存储在变量中的名称实际创建新列的人,我有以下工作要做。我对它的性能一无所知。有什么改进的建议吗?假设一个无名的新列总是被命名为V1安全吗

    colname <- as.name("users")
    # Google Analytics query is run with chosen metric and resulting data is assigned to DT
    DT2 <- DT[, sum(eval(colname, .SD)), by = country]
    setnames(DT2, "V1", as.character(colname))
    

    colname*这不是一个真正的答案,但我没有足够的街头信誉来发表评论:/

    无论如何,对于那些可能希望在数据表中使用存储在变量中的名称实际创建新列的人,我有以下工作要做。我对它的性能一无所知。有什么改进的建议吗?假设一个无名的新列总是被命名为V1安全吗

    colname <- as.name("users")
    # Google Analytics query is run with chosen metric and resulting data is assigned to DT
    DT2 <- DT[, sum(eval(colname, .SD)), by = country]
    setnames(DT2, "V1", as.character(colname))
    

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

    当从函数更新值时,RHS必须是一个列表对象,因此使用
    .SD
    上的循环和
    lappy
    就可以了

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

    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 vector
    nm <- c("a", "b")
    
    # Convert columns a and b to numeric type
    a1[, j = (nm) := lapply(.SD, as.numeric ), .SDcols = nm ]
    
    sapply(a1, class)
    #         a           b          c1 
    # "numeric"   "numeric" "character" 
    

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

    当从函数更新值时,RHS必须是一个列表对象,因此使用
    .SD
    上的循环和
    lappy
    就可以了

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

    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 vector
    nm <- c("a", "b")
    
    # Convert columns a and b to numeric type
    a1[, j = (nm) := lapply(.SD, as.numeric ), .SDcols = nm ]
    
    sapply(a1, class)
    #         a           b          c1 
    # "numeric"   "numeric" "character" 
    
    a1您可以试试这个
    你可以试试这个
    colname通过变量或函数从data.table检索多列:
    我发现
    .SDcols
    方式最优雅。

    通过变量或函数从data.table检索多列:
    我觉得
    .SDcols
    方式最优雅。

    谢谢你的回复。with=FALSE肯定解决了我的部分问题。但实际上,我想用列的总和替换列。我可以通过赋值右边的变量引用列名吗?事实上,我只是用一个不同的名称在外部存储了cumsum,这个名称在dt中不存在,而且工作正常。但这将是一整行额外的数据!不太优雅:)但有时它很有用。在这些情况下,最好以
    开头变量名。
    以避免在
    DT