我想将data.table内的一组列修改为因素。如果我事先知道各列的名称,那么我认为这很简单。
library(data.table)
dt1 <- data.table(a = (1:4), b = rep(c('a','b')), c = rep(c(0,1)))
dt1[,class(b)]
dt1[,b:=factor(b)]
dt1[,class(b)]
但是我没有,而是有一个变量名列表
vars.factors <- c('b','c')
我可以将因子函数毫无问题地应用于它们...
lapply(vars.factors, function(x) dt1[,class(get(x))])
lapply(vars.factors, function(x) dt1[,factor(get(x))])
lapply(vars.factors, function(x) dt1[,factor(get(x))])
但是我不知道如何重新分配或更新数据表中的原始列。
此失败...
lapply(vars.factors, function(x) dt1[,x:=factor(get(x))])
# Error in get(x) : invalid first argument
也是这样...
lapply(vars.factors, function(x) dt1[,get(x):=factor(get(x))])
# Error in get(x) : object 'b' not found
NB。我没有运气就尝试了here提出的答案。
是的,这很简单:
dt1[, (vars.factors) := lapply(.SD, as.factor), .SDcols=vars.factors]
在LHS
中(在j
中为:=),我们指定列的名称。如果一列已经存在,将对其进行更新,否则,将创建一个新列。在RHS中,我们遍历.SD
中的所有列(代表D ata的S ubset),并用.SD
指定应在.SDcols
中的列论点。
评论后:
请注意,我们需要用()
包裹LHS,以便对其进行[[evaluated)并在vars.factors
变量中获取列名。这是因为我们允许使用语法
DT[, col := value]
仅当分配一列时,通过将列名称指定为符号(不带引号),纯粹是为了方便。这将创建一个名为col
的列,并将其分配给value
。为了区分这两种情况,我们需要
()
。用()
对其进行包装就足以确定我们确实需要获取变量中的值。
> df1 = data.frame(dt1)
> df1[,vars.factors] = data.frame(sapply(df1[,vars.factors], factor))
> dt1 = data.table(df1)
> dt1
a b c
1: 1 1 b
2: 2 2 c
3: 3 3 b
4: 4 4 c
> str(dt1)
Classes ‘data.table’ and 'data.frame': 4 obs. of 3 variables:
$ a: int 1 2 3 4
$ b: Factor w/ 4 levels "1","2","3","4": 1 2 3 4
$ c: Factor w/ 2 levels "b","c": 1 2 1 2
- attr(*, ".internal.selfref")=<externalptr>
for (col in vars.factors)
set(dt, j=col, value=as.factor(dt1[[col]]))
vars.factors可以是整数或字符名称的向量,用于指定要修改的列。