R如何通过函数调用传递data.table参数

4

如果我有一个定义为data.table的数据表:

> dt <- data.table (x=c(1,2,3,4), y=c("y","n","y","m"), z=c("pickle",3,8,"egg"))

    > dt
        x   y        z 
    1:  1   y   pickle
    2:  2   n        3
    3:  3   y        8
    4:  4   m      egg

还有一个变量

    fn <- "z"

我知道可以通过以下方式从data.table中提取列:

    > dt[,fn, with=FALSE]

我不知道如何用data.table实现以下操作:

    > factorFunction <- function(df, fn) {
      df[,fn] <- as.factor(df[,fn])
      return(df)
     }

如果我设置fn="x"并调用factorFunction(data.frame(dt),fn),它可以正常工作。

所以我尝试使用data.table,但这不起作用。

    > factorFunction <- function(dt, fn) {
      dt[,fn, with=FALSE] <- as.factor(dt[,fn, with=FALSE])
      return(dt)
     }

在 sort.list(y) 中出现错误:'x' 必须是原子的才能进行 'sort.list' 的排序。 您是否对列表调用了 'sort' 函数?


顺便提一下,这是一种(非常不恰当的)方法:dt[,fn] <- as.factor(dt[,fn, with=FALSE][[1]]) 我认为它非常接近你所写的内容。 - Frank
3个回答

4
您可以尝试。
 dt[,(fn):= factor(.SD[[1L]]),.SDcols=fn]

如果有多列的话,使用lapply(.SD, factor)
将其封装成一个函数。
factorFunction <- function(df, fn) {
 df[, (fn):= factor(.SD[[1L]]), .SDcols=fn]
 }

 str(factorFunction(dt, fn))
 #Classes ‘data.table’ and 'data.frame':    4 obs. of  3 variables:
 #$ x: num  1 2 3 4
 #$ y: chr  "y" "n" "y" "m"
 #$ z: Factor w/ 4 levels "3","8","egg",..: 4 1 2 3

@DavidWagle 很高兴知道它能正常工作。我们在.SDcols中指定要用作子集的列,并在.SD[[1L]]中执行操作。在这里,我使用了1L将列表转换为向量。更一般地,它将是lapply(.SD, yourfuncton) - akrun

3
与 @akrun 的回答类似:
class(dt[[fn]])
#[1] "character"

setFactor <- function(DT, col) {
  #change the column type by reference
  DT[, c(col) := factor(DT[[col]])]
  invisible(NULL)
  }

setFactor(dt, fn)
class(dt[[fn]])
#[1] "factor"

或者直接使用 setsetFactor <- function(DT, col) set(DT, j = col, value = factor(DT[[col]]) ) - Frank

2
我不建议这样做,因为这非常不符合惯用语的使用方式:
factorFunction <- function(df,col){
  df[,col] <- factor(df[[col]])
  df
} 

好处是它可以在基本R和data.table中使用:

df <- setDF(copy(dt))

class(df[[fn]]) # character
df <- factorFunction(df,fn)
class(df[[fn]]) # factor

class(dt[[fn]]) # character
dt <- factorFunction(dt,fn)
class(dt[[fn]]) # factor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接