Mam problem z użyciem data.table: Jak przekonwertować klasy kolumn? Oto prosty przykład: z data.frame nie mam problemu z konwersją, z data.table po prostu nie wiem jak:
df <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
#One way: http://stackoverflow.com/questions/2851015/r-convert-data-frame-columns-from-factors-to-characters
df <- data.frame(lapply(df, as.character), stringsAsFactors=FALSE)
#Another way
df[, "value"] <- as.numeric(df[, "value"])
library(data.table)
dt <- data.table(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
dt <- data.table(lapply(dt, as.character), stringsAsFactors=FALSE)
#Error in rep("", ncol(xi)) : invalid 'times' argument
#Produces error, does data.table not have the option stringsAsFactors?
dt[, "ID", with=FALSE] <- as.character(dt[, "ID", with=FALSE])
#Produces error: Error in `[<-.data.table`(`*tmp*`, , "ID", with = FALSE, value = "c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2)") :
#unused argument(s) (with = FALSE)
Czy brakuje mi czegoś oczywistego?
Aktualizacja z powodu posta Matthew: Wcześniej korzystałem ze starszej wersji, ale nawet po aktualizacji do 1.6.6 (wersja, której używam teraz) nadal pojawia się błąd.
Aktualizacja 2: Powiedzmy, że chcę przekonwertować każdą kolumnę „współczynnika” klasy na kolumnę „znakową”, ale nie wiem z góry, która kolumna należy do której klasy. Za pomocą data.frame mogę wykonać następujące czynności:
classes <- as.character(sapply(df, class))
colClasses <- which(classes=="factor")
df[, colClasses] <- sapply(df[, colClasses], as.character)
Czy mogę zrobić coś podobnego z data.table?
Aktualizacja 3:
sessionInfo () R wersja 2.13.1 (2011-07-08) Platforma: x86_64-pc-mingw32 / x64 (64-bit)
locale:
[1] C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.6.6
loaded via a namespace (and not attached):
[1] tools_2.13.1
r
data.table
Christoph_J
źródło
źródło
data.table
metodach są inne niż w przypadkudata.frame
#Produces error
. I tak +1. Nie widzę żadnego błędu, którą wersję masz? Istnieje jednak problem w tym obszarze, został już wcześniej poruszony, a FR # 1224 i FR # 1493 mają wysoki priorytet do rozwiązania. Jednak odpowiedź Andrie jest najlepsza.invalid times argument
błędu? Pracuj dobrze dla mnie. Którą wersję masz?Odpowiedzi:
Dla pojedynczej kolumny:
Korzystanie
lapply
ias.character
:źródło
convcols
kolumn.dt[,lapply(.SD,as.numeric),.SDcols=convcols]
jest prawie natychmiastowy, adt[,convcols:=lapply(.SD,as.numeric),.SDcols=convcols]
prawie zawiesza R, więc domyślam się, że robię to źle. Dziękiset()
np.for (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
[end quote]Spróbuj tego
źródło
Filter
funkcji do identyfikacji kolumn, na przykład:changeCols<- names(Filter(is.character, DT))
changeCols <- names(DT)[sapply(DT, is.character)]
.Podnosząc komentarz Matta Dowle do odpowiedzi Geneoramy ( https://stackoverflow.com/a/20808945/4241780 ), aby uczynić ją bardziej oczywistą (zgodnie z zaleceniami ), możesz użyć
for(...)set(...)
.Utworzony 12.02.2020 przez pakiet reprex reprex (v0.3.0)
Zobacz inny komentarz Matta pod adresem https://stackoverflow.com/a/33000778/4241780, aby uzyskać więcej informacji.
Edytować.
Jak zauważyli Espen i in
help(set)
,j
może to być „Nazwa (y) kolumny (znaki) (znak) lub liczba (y) (liczba całkowita), do której ma zostać przypisana wartość, gdy kolumny już istnieją”. Taknames_factors <- c(1L, 3L)
też będzie działać.źródło
names_factors
tu jest. Wydaje mi się, że pochodzi ze stackoverflow.com/a/20808945/1666063, więcnames_factors = c('fac1', 'fac2')
w tym przypadku jest to nazwa kolumn, ale mogą to być również numery kolumn, na przykład 1; ncol (dt), które konwertują wszystkie kolumnyTo ZŁY sposób na zrobienie tego! Zostawiam tę odpowiedź tylko na wypadek, gdyby rozwiązała inne dziwne problemy. Te lepsze metody są prawdopodobnie częściowo wynikiem nowszych wersji data.table ... więc warto udokumentować ten trudny sposób. Poza tym jest to ładny przykład
eval
substitute
składni.co ci daje
źródło
set()
np.for (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
set
jest bardziej odpowiednie.for(...)set(...)
tutaj: stackoverflow.com/a/33000778/403310Próbowałem kilku podejść.
, lub w przeciwnym wypadku
źródło
Zapewniam bardziej ogólny i bezpieczniejszy sposób na zrobienie tego,
Funkcja
..
zapewnia, że otrzymamy zmienną spoza zakresu data.table; set_colclass ustawi klasy twoich col. Możesz go używać w ten sposób:źródło
Jeśli masz listę nazw kolumn w data.table, chcesz zmienić klasę do:
źródło
dt[, c(convert_to_character) := lapply(.SD, as.character), .SDcols=convert_to_character]
przypisać przez odniesienie, zamiast używać wolniejszego przypisywania data.frame.próbować:
źródło