2017-01-08 6 views
7

Chcę zmienić poziomy czynników w kolumnie przy użyciu setattr. Jednak po wybraniu kolumny standardowy sposób (0123), nie jest aktualizowany. Z drugiej strony przy wyborze kolumny w niekonwencjonalny sposób w ustawieniu data.table - a mianowicie przy użyciu $ - działa.Zmienianie poziomów czynników w kolumnie z setattr jest wrażliwe na sposób utworzenia kolumny

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 

Czuje się jakbym brakuje niektórych data.table (R?) Podstawy tutaj. Czy ktoś może wyjaśnić, co się dzieje?


Znalazłem dwa inne post setattr i levels:

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

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

Obaj wykorzystywane $ aby wybrać kolumnę. Żadne z nich nie wspomniało o metodzie [ , col].

+0

Zgodnie z dokumentami, nie powinno być problemu - * "setattr" akceptuje dowolne wejście; np. lista, kolumny "data.frame" lub "data.table". * Otrzymuję ten sam problem, co ty. – thelatemail

+1

To zachowanie ma dla mnie sens. Fwiw, zawsze robię po prostu setattr wewnątrz j, który wydaje się działać dobrze tutaj: 'd [, setattr (x," levels ", lev)]' – Frank

+1

@Frank Dziękuję za twoją opinię. Byłem tak zmęczony wczoraj, że udało mi się tylko nacisnąć strzałkę w górę, zanim zasnąłem. Czy marzyłeś o słodkich snach (czy było to koszmarem?) Po pół-traumatycznym doświadczeniu "j". Przynajmniej miałem rację w moim "Wydaje mi się, że brakuje mi podstaw" data.table "(" R "?) Here_";) – Henrik

Odpowiedz

8

To może pomóc zrozumieć, jeśli spojrzeć na adres z obu wyrażeń:

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


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

Należy pamiętać, że adres z pierwszego wyrazu nie zmienia się, gdy nazywają go kilka razy, podczas gdy drugi wyraz robi co oznacza, że ​​robi kopię kolumny ze względu na dynamiczny charakter adresu, więc nie będzie ona miała wpływu na oryginalny plik data.table.

+0

@Henrik - z mojej naiwnej perspektywy wydaje się to sprzeczne z dokumentami. Przynajmniej uważam, że należy to zauważyć. – thelatemail

+0

Myślę, że to rozsądne, biorąc pod uwagę to, co zwykle robisz na pozycji 'j', tj. Podsumowując, tworząc nowe kolumny i nowe listy, chyba że używasz': = '. Ale zgadnij. – Psidom

+0

@Psidom Tak, to ma sens. Dzięki. W mojej niewiedzy myślałem, że jestem w stanie zrobić "tylko" prostą selekcję kolumny, w sensie '$'/subsetting of select, ale zrobienie tego w 'j' jest oczywiście bardziej wyborem stylu kalkulacyjnego. Rzeczywiście, brakowało mi podstaw "danych.table". – Henrik