2017-01-08 2 views
7

Я хочу изменить уровни факторов столбца, используя setattr. Однако, когда выбран столбец, стандартный номер data.table (dt[ , col]), levels не обновляются. С другой стороны, при выборе столбца неортодоксальным способом в настройке data.table, а именно с использованием $ -it работает.Изменение уровней факторов в столбце с setattr чувствительно к тому, как был создан столбец

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.table (R?) Основы здесь. Может ли кто-нибудь объяснить, что происходит?


Я нашел две другие должности на setattr и levels:

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

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

Оба они использовали $ для выбора колонки. Ни один из них не упомянул путь [ , col].

+0

В соответствии с документами не должно быть проблем - * 'setattr' принимает любые входные данные; например, список, столбцы «data.frame» или «data.table». * Я получаю ту же проблему, что и вы. – thelatemail

+1

Такое поведение имеет смысл для меня. Fwiw, я всегда просто делаю setattr внутри j, что, кажется, отлично работает здесь: 'd [, setattr (x," levels ", lev)]' – Frank

+1

@Frank Благодарим вас за отзыв. Я так устал вчера, поэтому мне только удалось нажать стрелку вверх, прежде чем я заснул. Мечтали сладкие мечты (или это были кошмары?) После полутравматического «j» опыта. По крайней мере, я был прав в своем «_It чувствует, что мне не хватает каких-то оснований' data.table' ('R'?) Here_";) – Henrik

ответ

8

Это может помочь понять, если вы посмотрите на адрес из обоих выражений:

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


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

Обратите внимание, что адрес из первого выражения не изменится, когда вы называете его несколько раз, в то время как второе выражение делает который указывает, что он делает копию столбца из-за динамического характера адреса, поэтому setattr на нем не повлияет на исходную таблицу данных.

+0

@ Хенрик - из моей наивной перспективы это противоречит документам. Как минимум, я думаю, это следует отметить. – thelatemail

+0

Я думаю, что разумно учитывать то, что вы обычно делаете в позиции 'j', т. Е. Подведение итогов, создание новых столбцов и новых списков, если вы не используете': = '. Но просто догадаться. – Psidom

+0

@Psidom Да, это имеет смысл. Благодарю. По моему невежеству, я думал, что смог сделать «только» простой выбор столбца в смысле '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '. В самом деле, у меня не было оснований 'data.table'. – Henrik

Смежные вопросы