Kiedy przekształcam czynnik na wartość liczbową lub całkowitą, otrzymuję kody poziomu podstawowego, a nie wartości jako liczby.
f <- factor(sample(runif(5), 20, replace = TRUE))
## [1] 0.0248644019011408 0.0248644019011408 0.179684827337041
## [4] 0.0284090070053935 0.363644931698218 0.363644931698218
## [7] 0.179684827337041 0.249704354675487 0.249704354675487
## [10] 0.0248644019011408 0.249704354675487 0.0284090070053935
## [13] 0.179684827337041 0.0248644019011408 0.179684827337041
## [16] 0.363644931698218 0.249704354675487 0.363644931698218
## [19] 0.179684827337041 0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218
as.numeric(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
as.integer(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
Muszę paste
skorzystać z prawdziwych wartości:
as.numeric(paste(f))
## [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
## [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901
Czy jest lepszy sposób na konwersję współczynnika na liczbę?
attributes(f)
), więc nie sądzę, że coś jest nie takas.numeric(paste(f))
. Być może lepiej byłoby pomyśleć, dlaczego (w konkretnym kontekście) dostajesz czynnik w pierwszej kolejności i spróbować go zatrzymać. Np. Czydec
argument jestread.table
ustawiony poprawnie?df %>% convert(num(column))
. Lub jeśli masz wektor czynnikowy, którego możesz użyćas_reliable_num(factor_vector)
Odpowiedzi:
Zobacz sekcję Ostrzeżenie w
?factor
:FAQ na temat R zawiera podobne porady .
Dlaczego jest
as.numeric(levels(f))[f]
bardziej skuteczny niżas.numeric(as.character(f))
?as.numeric(as.character(f))
jest efektywnyas.numeric(levels(f)[f])
, dlatego konwersja nalength(x)
wartości liczbowe jest przeprowadzana raczej nanlevels(x)
wartościach niż na wartościach. Różnica prędkości będzie najbardziej widoczna dla długich wektorów z kilkoma poziomami. Jeśli wartości są w większości unikalne, nie będzie dużej różnicy prędkości. Jakkolwiek wykonasz konwersję, jest mało prawdopodobne, aby ta operacja była wąskim gardłem w twoim kodzie, więc nie przejmuj się tym zbytnio.Niektóre czasy
źródło
R ma wiele (nieudokumentowanych) funkcji ułatwiających przeliczanie czynników:
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
Ale irytujące jest to, że nie można nic poradzić na czynnik -> konwersja liczbowa . Jako rozszerzenie odpowiedzi Joshuy Ulricha proponuję przezwyciężyć to pominięcie, definiując własną funkcję idiomatyczną:
które możesz zapisać na początku skryptu, a nawet lepiej w
.Rprofile
pliku.źródło
as.integer(factor)
zwróci podstawowe kody liczb całkowitych (jak pokazano w sekcji przykładów?factor
). Prawdopodobnie dobrze jest zdefiniować tę funkcję w globalnym środowisku, ale możesz powodować problemy, jeśli faktycznie zarejestrujesz ją jako metodę S3.factor->numeric
konwersję dużo przed zdając sobie sprawy, że w rzeczywistości jest to wada R: niektóre funkcje wygoda powinny być dostępne ... Wywołanie toas.numeric.factor
ma sens dla mnie, ale YMMV.v=NA;as.numeric.factor(v)
lubv='something';as.numeric.factor(v)
, to powinno, w przeciwnym razie gdzieś dzieje się coś dziwnego.Najłatwiejszym sposobem byłoby użycie
unfactor
funkcji z pakietu varhandleTen przykład może być szybkim początkiem:
źródło
unfactor
pierwszym, a następnie konwertuje funkcyjne do wpisywania danych charakter nawróceni powrotem do numerycznej. Piszunfactor
w konsoli, a zobaczysz go w środku funkcji. Dlatego tak naprawdę nie daje lepszego rozwiązania niż to, które już pytał.unfactor
Funkcja dba o rzeczy, które nie mogą być konwertowane na numeryczną. Sprawdź przykłady whelp("unfactor")
library("varhandle")
) (jak wspomniałem w pierwszym wierszu mojej odpowiedzi !!)as.numeric()
ias.character()
w niewłaściwej kolejności;) To, co robi twoja część kodu, polega na przekształceniu wskaźnika poziomu czynnika w matrycę znaków, więc to, co będziesz miał na jest wektorem znaków, który zawiera pewne liczby, które zostały kiedyś przypisane do określonego poziomu twojego współczynnika. Funkcje zawarte w tym pakiecie zapobiegają takim pomyłkomUwaga: ta konkretna odpowiedź nie służy do konwersji czynników o wartościach liczbowych na liczby, lecz do konwersji czynników kategorycznych na odpowiadające im liczby poziomów.
Każda odpowiedź w tym poście nie generowała dla mnie wyników, NA były generowane.
Dla mnie zadziałało to -
źródło
y<-factor(c("5","15","20","2")); unclass(y) %>% as.numeric
Zwraca 4,1,3,2, a nie 5,15,20,2. To wydaje się niepoprawne informacje.as.numeric(y)
powinno być dobrze, bez potrzebyunclass()
. Ale znowu nie o to chodziło w tym pytaniu. Ta odpowiedź nie jest tutaj odpowiednia.Jest to możliwe tylko w przypadku, gdy etykiety czynników odpowiadają oryginalnym wartościom. Wyjaśnię to na przykładzie.
Załóżmy, że dane są wektorem
x
:Teraz utworzę czynnik z czterema etykietami:
1)
x
jest z typem double,f
jest z typem integer. To pierwsza nieunikniona utrata informacji. Czynniki są zawsze przechowywane jako liczby całkowite.2) Nie ma możliwości powrotu do pierwotnych wartości (10, 20, 30, 40), które są
f
dostępne tylko . Widzimy, żef
zawiera tylko wartości całkowite 1, 2, 3, 4 i dwa atrybuty - listę etykiet („A”, „B”, „C”, „D”) i atrybut klasy „współczynnik”. Nic więcej.Aby powrócić do pierwotnych wartości, musimy znać wartości poziomów zastosowanych przy tworzeniu współczynnika. W tym przypadku
c(10, 20, 30, 40)
. Jeśli znamy oryginalne poziomy (w odpowiedniej kolejności), możemy wrócić do pierwotnych wartości.Będzie to działać tylko w przypadku, gdy zdefiniowano etykiety dla wszystkich możliwych wartości w oryginalnych danych.
Więc jeśli będziesz potrzebować oryginalnych wartości, musisz je zachować. W przeciwnym razie istnieje duża szansa, że nie będzie można do nich wrócić tylko z jednego powodu.
źródło
Możesz użyć,
hablar::convert
jeśli masz ramkę danych. Składnia jest łatwa:Próbka df
Rozwiązanie
daje Ci:
Lub jeśli chcesz, aby jedna kolumna była liczbą całkowitą i jedną liczbą:
prowadzi do:
źródło
Wygląda na to, że rozwiązanie as.numeric (poziomy (f)) [f] nie działa już z R 4.0.
Alternatywne rozwiązanie:
źródło
Z wielu odpowiedzi, które mogłem przeczytać, jedynym możliwym sposobem było zwiększenie liczby zmiennych zgodnie z liczbą czynników. Jeśli masz zmienną „zwierzak” z poziomami „pies” i „kot”, skończyłbyś na pet_dog i pet_cat.
W moim przypadku chciałem pozostać przy tej samej liczbie zmiennych, po prostu tłumacząc zmienną czynnikową na zmienną liczbową, w sposób, który można zastosować do wielu zmiennych o wielu poziomach, na przykład cat = 1 i dog = 0.
Poniżej znajdziesz odpowiednie rozwiązanie:
źródło
późno do gry, przypadkowo, znalazłem
trimws()
można konwertowaćfactor(3:5)
doc("3","4","5")
. Następnie możesz zadzwonićas.numeric()
. To jest:źródło
trimws
was.character
sposób opisany w zaakceptowanej odpowiedzi? Wydaje mi się, że chyba, że rzeczywiście miałeś spację, którą musiałeś usunąć,trimws
po prostu wykonam mnóstwo niepotrzebnej pracy z wyrażeniami regularnymi, aby zwrócić ten sam wynik.