代码之家  ›  专栏  ›  技术社区  ›  ShanZhengYang

如何从函数参数定义r data.table/data.frame列?

  •  2
  • ShanZhengYang  · 技术社区  · 6 年前

    我在一个R包中创建了一个函数,它接受几个参数。其中一个参数是r data.table的列的名称。

    假设我想创建一个包含所有值的列 42 . 对于r data.table dt 我会这样做:

    dt[, column_name:=42]
    

    对于r data.frame,我会:

    df$column_name = 42
    

    我希望函数将定义 column_name . 例如,函数 func 呼叫人

    func(dt, col='hey')
    

    会通过的 hey 作为data.table列的新名称。

    下面是一个具体的例子

    renamer = function(colname, dt){
        ## do calculations on dt
        dt[, colname:= 42]
    }
    

    如果我调用函数 renamer(colname = 'foo', dt=dt) ,结果列名称仍将为 colname 不是我传递的值“foo”。

    新列应为字符串“foo”

    setnames(dt, "oldname", "newname")
    

    编辑:我认为这个问题应该澄清:

    以下是数据表:

    > library(data.table)
    > DT = data.table(ID = c("b","b","b","a","a","c"), a = 1:6, b = 7:12, c = 13:18)
    > DT
       ID a  b  c
    1:  b 1  7 13
    2:  b 2  8 14
    3:  b 3  9 15
    4:  a 4 10 16
    5:  a 5 11 17
    6:  c 6 12 18
    

    我想创建一个函数,这样这个列的新名称就是用户传递它的字符串。

    例如

    colnamer = function(newcolumname, datatable){
        ## do calculations on dt
        ## create a column with whatever string is passed via 'newcolumnname'
    }
    

    如果用户呼叫 colnamer('foobar', DT) ,我希望结果是

    > DT
       ID a  b  c  foobar
    1:  b 1  7 13   ...
    2:  b 2  8 14   ...
    3:  b 3  9 15   ...
    4:  a 4 10 16   ...
    5:  a 5 11 17   ...
    6:  c 6 12 18   ...
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   tstev    6 年前

    编辑 :更改为OP新的可复制示例,根据OP的问题陈述提出两条建议;

    library(data.table) 
    DT <- data.table(ID = c("b","b","b","a","a","c"), 
                     a = 1:6, b = 7:12, c = 13:18)
    
    colnamer1 <- function(newcolumname, datatable) {
      ## do calculations on dt
      ## create a column with whatever string is passed via 'newcolumnname'
      set(datatable, j = newcolumname, value = 42)
    }
    
    colnamer2 <- function(newcolumname, datatable) {
      ## do calculations on dt
      ## create a column with whatever string is passed via 'newcolumnname'
      dt[, (newcolumname) := 42]
    }
    
    colnamer1("name_me", DT)
    colnamer2("name_me_too", DT)
    DT
    #    ID a  b  c name_me name_me_too
    # 1:  b 1  7 13      42          42
    # 2:  b 2  8 14      42          42
    # 3:  b 3  9 15      42          42
    # 4:  a 4 10 16      42          42
    # 5:  a 5 11 17      42          42
    # 6:  c 6 12 18      42          42
    

    一个可能的 data.frame 解决方案?尽管自从采用 data.table 我的 数据帧 -ING有点生锈。当你的问题涉及到 数据帧 .

    df <- data.frame(ID = c("b","b","b","a","a","c"), 
                     a = 1:6, b = 7:12, c = 13:18)
    df_colnamer <- function(name_me, df) {
      new_df <- df
      new_df[[name_me]] <- 42
      new_df
    }
    new_df <- df_colnamer("foo", df)
    new_df
    #   ID a  b  c foo
    # 1  b 1  7 13  42
    # 2  b 2  8 14  42
    # 3  b 3  9 15  42
    # 4  a 4 10 16  42
    # 5  a 5 11 17  42
    # 6  c 6 12 18  42