2
votes

I have created a function in an R package which takes several arguments. One of these arguments is the name of a column for an R data.table.

Let's say I wanted to create a column with all values 42. For R data.table dt, I would do:

dt[, column_name:=42]

For R data.frame, I would do:

df$column_name = 42

I would like the function to take as an argument something that would define column_name. For instance, the function func called by

func(dt, col='hey')

would pass hey as the new name of the data.table column.

Here's a concrete example

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

If I call the function renamer(colname = 'foo', dt=dt), the resulting column name will still be colname, not the value I passed, 'foo'.

The new column should be the string 'foo'

How could I do this? I've also tried with R data.frame, or trying something with

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

EDIT: I think this question should be clarified:

Here is a data.table:

> 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

I would like to create a function such that the new name of the column will be the string the user passes it.

e.g.

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

If the user calls colnamer('foobar', DT), I would like the result to be

> 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
Not too sure what you want? Do you want the column name for colname in renamer function to change or do you want to change the contents of colname? In the latter case I think this would work; dt[, get(colname) := 42]tstev
@tstev I want the new column to be named a string the user passes in the function. e.g. in the above, renamer(colname = 'foo', dt=dt), the new column would fooShanZhengYang
@tstev The error I have with get(colname) is Error in get(colname) : object 'foo' not foundShanZhengYang
like dt[[colname]] <- 42 ?Moody_Mudskipper
I am not a data.table expert but I think the line in renamer should be dt[, (colname) := 42].markus

1 Answers

1
votes

EDIT: Changed to OP's new reproducible example with two suggestions that worked as per OP's problem statement;

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

A possible data.frame solution? Although ever since adopting data.table my data.frame-ing is a bit rusty. Perhaps there is a more elegant solution for your problem when it comes to a data.frame.

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