我想使用setattr更改列的因子级别。但是,当选择标准data.table方式(dt[ , col])列时,levels不会更新。另一方面,在data.table设置中(即使用$)以非正统的方式选择列时,它可以工作。

library(data.table)

# Some data
d <- data.table(x = factor(c("b", "a", "a", "b")), y = 1:4)
d
#    x y
# 1: b 1
# 2: a 2
# 3: a 3
# 4: b 4

# We want to change levels of 'x' using setattr
# New desired levels
lev <- c("a_new", "b_new")

# Select column in the standard data.table way
setattr(x = d[ , x], name = "levels", value = lev)

# Levels are not updated
d
#    x y
# 1: b 1
# 2: a 2
# 3: a 3
# 4: b 4

# Select column in a non-standard data.table way using $
setattr(x = d$x, name = "levels", value = lev)

# Levels are updated
d
#        x y
# 1: b_new 1
# 2: a_new 2
# 3: a_new 3
# 4: b_new 4

# Just check if d[ , x] really is the same as d$x
d <- data.table(x = factor(c("b", "a", "a", "b")), y = 1:4)
identical(d[ , x], d$x)
# [1] TRUE
# Yes, it seems so


感觉好像我在这里缺少一些data.tableR?)基础。谁能解释这是怎么回事?



我在setattrlevels上找到了另外两个帖子:

setattr on levels preserving unwanted duplicates (R data.table)

How does one change the levels of a factor column in a data.table

他们两个都使用$选择列。他们都没有提到[ , col]方式。

最佳答案

如果您同时查看两个表达式中的地址,可能会有所帮助:

address(d$x)
# [1] "0x10e4ac4d8"
address(d$x)
# [1] "0x10e4ac4d8"


address(d[,x])
# [1] "0x105e0b520"
address(d[,x])
# [1] "0x105e0a600"


请注意,第一个表达式的地址在您多次调用时不会更改,而第二个表达式会更改,这表明由于该地址的动态性质,它正在复制该列,因此对它的setattr对原始data.table没有影响。

关于r - 使用setattr更改列上的因子水平对创建列的方式很敏感,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41539202/

10-12 17:49