Transformacja klas kolumn *some* w data.table

Chcę przekonwertować podzbiór data.table siodła do nowej klasy. Jest popularne pytanie /
https://coderoad.ru/7813578/
/, Ale odpowiedź tworzy nowy obiekt i nie działa z obiektem początkowym.

Weź tego przykładu:


dat <- data.frame/ID=c/rep/"A", 5/, rep/"B",5//, Quarter=c/1:5, 1:5/, value=rnorm/10//
cols <- c/'ID', 'Quarter'/


Jak najlepiej konwertować tylko kolumny
cols

w /na przykład/ czynnik? W zwykłej data.frame Mogłaś to zrobić:


dat[, cols] <- lapply/dat[, cols], factor/


Ale to nie działa data.table, I też nie działa


dat[, .SD := lapply/.SD, factor/, .SDcols = cols]


Komentarz w związku z tym pytanie Matt Dowla /Od grudnia 2013 roku/ Zakłada, że ​​następujące prace normalnie, ale wydaje się trochę mniej eleganckie.


for /j in cols/ set/dat, j = j, value = factor/dat[[j]]//


Czy jest obecnie najlepsza odpowiedź data.table /I.E. Krótszy + nie generuje zmiennej licznika/, Lub powinienem po prostu użyć powyższego +
rm/j/

?
Zaproszony:

Marian

Potwierdzenie od:

Oprócz korzystania z opcji proponowanej przez Matt Dulum, inny sposób na zmianę klas kolumnowych jest następujący:


dat[, /cols/ := lapply/.SD, factor/, .SDcols = cols]


Za pomocą operatora.
:=

, Aktualizujesz datatable połączyć. I czy działał, czy działało:


> sapply/dat,class/
ID Quarter value
"factor" "factor" "numeric"


Jak zaproponowano @MattDowle W komentarzach można również użyć kombinacji
for/.../ set/.../

w następujący sposób:


for /col in cols/ set/dat, j = col, value = factor/dat[[col]]//


Co da ten sam wynik. Trzecią opcją jest:


for /col in cols/ dat[, /col/ := factor/dat[[col]]/]


Na parametrze małych zestawów danych
for/.../ set/.../

około trzy razy szybciej niż parametr
lapply

/Ale to nie ma znaczenia, ponieważ jest to mały zestaw danych./. Na dużych zestawach danych /na przykład, 2 Milion Row/ Każde z tych podejść zajmuje mniej więcej tak samo. Do testowania w większym zestawie danych używałem:


dat <- data.table/ID=c/rep/"A", 1e6/, rep/"B",1e6//,
Quarter=c/1:1e6, 1:1e6/,
value=rnorm/10//


Czasami musisz to zrobić trochę innego /Na przykład, gdy wartości liczbowe są przechowywane jako czynnik/. Wtedy musisz użyć czegoś takiego:


dat[, /cols/ := lapply/.SD, function/x/ as.integer/as.character/x///, .SDcols = cols]



WARNING:

Następujące wyjaśnienie

nie

to A.
data.table

- Wyczyść rzeczy do zrobienia rzeczy. datatable nie aktualizowany przez odniesienie, ponieważ kopia jest tworzona i przechowywana w pamięci /Jak wskazano @Frank/,, Co zwiększa użycie pamięci. Jest to bardziej jak dodatek do wyjaśnienia pracy
with = FALSE

.

Jeśli chcesz zmienić klasy kolumn, tak jak to zrobiłeś dataframe, Musisz dodać
with = FALSE

w następujący sposób:


dat[, cols] <- lapply/dat[, cols, with = FALSE], factor/


I czy działał, czy działało:


> sapply/dat,class/
ID Quarter value
"factor" "factor" "numeric"


Jeśli nie dodasz
with = FALSE

, że datatable oceni się
dat[, cols]

jako wektor. Sprawdź różnicę w wyjściu między
dat[, cols]

i
dat[, cols, with = FALSE]

:


> dat[, cols]
[1] "ID" "Quarter"

> dat[, cols, with = FALSE]
ID Quarter
1: A 1
2: A 2
3: A 3
4: A 4
5: A 5
6: B 1
7: B 2
8: B 3
9: B 4
10: B 5

Paweł

Potwierdzenie od:

możesz użyć
.SDcols

:


dat[, cols] <- dat[, lapply/.SD, factor/, .SDcols=cols]

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się