我可以以编程方式更新data.table中的一组列的类型(至因子)吗?

问题描述 投票:5回答:3

我想将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提出的答案。

r data.table r-factor
3个回答
12
投票

是的,这很简单:

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

为了区分这两种情况,我们需要()。用()对其进行包装就足以确定我们确实需要获取变量中的值。


2
投票
使用数据框:

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


1
投票
也可以做

for (col in vars.factors) set(dt, j=col, value=as.factor(dt1[[col]]))

vars.factors可以是整数或字符名称的向量,用于指定要修改的列。

请参阅https://stackoverflow.com/a/33000778/4241780了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.