Poza tym przy użyciu opcji jak sugeruje Matt Dowle, inny sposób zmiany klasy kolumn jest następujące:
dat[, (cols) := lapply(.SD, factor), .SDcols=cols]
Używając :=
operator aktualizujesz datatable według referencji. Sprawdzenie, czy to działało:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Jak suggeted przez @MattDowle w komentarzach, można również użyć kombinacji for(...) set(...)
następująco:
for (col in cols) set(dat, j = col, value = factor(dat[[col]]))
które dadzą ten sam wynik. Trzecią alternatywą jest:
for (col in cols) dat[, (col) := factor(dat[[col]])]
na mniejszą zbiorów danych, opcja for(...) set(...)
jest około trzy razy szybciej niż opcja lapply
(ale to naprawdę nie ma znaczenia, ponieważ jest to mały zbiór danych). W przypadku większych zestawów danych (na przykład 2 miliony wierszy) każde z tych podejść zajmuje mniej więcej tyle samo czasu. Do badania na większej zbiorze, użyłem:
dat <- data.table(ID=c(rep("A", 1e6), rep("B",1e6)),
Quarter=c(1:1e6, 1:1e6),
value=rnorm(10))
Czasami trzeba będzie zrobić to trochę inaczej (na przykład, gdy wartości liczbowe są przechowywane jako czynnik).Następnie trzeba użyć czegoś takiego:
dat[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols=cols]
UWAGA:Poniższe wyjaśnienie jest niedata.table
-way robienia rzeczy. Dane nie są aktualizowane przez odniesienie, ponieważ kopia jest tworzona i przechowywana w pamięci (jak wskazano przez @Frank), co zwiększa wykorzystanie pamięci. Jest to raczej dodatek w celu wyjaśnienia działania with=FALSE
.
Gdy chcesz zmienić klasach kolumnie w ten sam sposób, jak można zrobić z dataframe, trzeba dodać with = FALSE
następująco:
dat[, cols] <- lapply(dat[, cols, with = FALSE], factor)
Sprawdzenie czy to działało:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Jeśli nie dodasz with = FALSE
, datatable oceni jako dat[, cols]
jako wektor. Sprawdź różnicę w wydajności pomię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
wierzę metoda Matt Dowle zaleca byłoby najlepsze. W końcu jest autorem * data.table *. –
To prawda, ale komentarz pochodził z 2013 roku i od tamtej pory było wiele aktualizacji pakietów, więc pomyślałem, że warto wyrzucić tę żyłkę. – arvi1000
Więcej szczegółów na temat 'for (...) set (...)' idiom added ostatnio tutaj: http://stackoverflow.com/a/33000778/403310 –