2015-06-18 57 views
3

,所以如果我有一個data.table定義爲:R 1至函數傳遞參數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,但這並不在sort.list工作

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

錯誤(Y): 'X' 必須是原子的 'sort.list' 你有沒有在名單上叫'排序'?

+0

順便說一句,這裏的一個(非常unidiomatic)方式:'dt [,fn] < - as.factor(dt [,fn,with = FALSE] [[1]])''這與我寫的非常接近,我想。 – Frank

回答

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 
+0

好的,這個工程。謝謝! –

+0

@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" 
+0

或者只是使用'set':'setFactor < - 函數(DT,col)set(DT,j = col,value = factor(DT [[col] ]))' – Frank

2

我不建議這樣做,因爲這是非常unidiomatic:

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