Mam ramkę danych. Zadzwońmy do niego bob
:
> head(bob)
phenotype exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
Chciałbym połączyć wiersze tej ramki danych (będzie to kolejne pytanie). Ale spójrz:
> class(bob$phenotype)
[1] "factor"
Bob
kolumny są czynnikami. Na przykład:
> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)" "c(3, 3, 3, 3, 3, 3)"
[3] "c(29, 29, 29, 30, 30, 30)"
Nie zaczynam tego rozumieć, ale sądzę, że są to wskaźniki poziomów czynników kolumn (dworu króla Karaktakusa) bob
? Nie tego potrzebuję.
O dziwo mogę bob
ręcznie przejść przez kolumny i zrobić
bob$phenotype <- as.character(bob$phenotype)
co działa dobrze. Po wpisaniu mogę uzyskać ramkę data.frame, której kolumny to raczej znaki niż czynniki. Więc moje pytanie brzmi: jak mogę to zrobić automatycznie? Jak przekonwertować ramkę data.frame z kolumnami czynnikowymi na ramkę data.frame z kolumnami znaków bez konieczności ręcznego przechodzenia przez każdą kolumnę?
Pytanie dodatkowe: dlaczego działa podejście ręczne?
bob
.Odpowiedzi:
Po prostu śledzę Matta i Dirka. Jeśli chcesz odtworzyć istniejącą ramkę danych bez zmiany opcji globalnej, możesz ją odtworzyć za pomocą instrukcji Apply:
Spowoduje to konwersję wszystkich zmiennych do klasy „znak”, jeśli chcesz tylko przeliczać współczynniki, zobacz rozwiązanie Marka poniżej .
Jak zauważa @adley, poniższe są bardziej zwięzłe.
W obu przypadkach
lapply
wyświetla listę; jednak ze względu na magiczne właściwości R użycie[]
w drugim przypadku zachowuje klasę data.framebob
obiektu, eliminując w ten sposób potrzebę ponownej konwersji na data.frame przy użyciuas.data.frame
argumentustringsAsFactors = FALSE
.źródło
type.convert
po odlaniu wszystkocharacter
, przekształconej następniefactors
z powrotemcharacter
ponownie.bob[] <-
w przykładzie lubbob <-
? pierwszy zachowuje data.frame; drugi zmienia data.frame na listę, upuszczając nazwy rown. Zaktualizuję odpowiedźiris[] <- lapply(iris, function(x) if (is.factor(x)) as.character(x) else {x})
Aby zastąpić tylko czynniki:
W pakiecie dplyr w wersji 0.5.0
mutate_if
wprowadzono nową funkcję :Mruczenie pakietów z RStudio daje kolejną alternatywę:
źródło
purrr
wiersz zwraca listę, a niedata.frame
!i
wektor będący wektoremcolnames()
.Opcja globalna
może być czymś, co chcesz ustawić
FALSE
w plikach startowych (np. ~ / .Rprofile). Proszę zobaczyćhelp(options)
.źródło
Jeśli zrozumiesz, w jaki sposób są przechowywane czynniki, możesz uniknąć korzystania z funkcji opartych na aplikacjach, aby to osiągnąć. Co wcale nie oznacza, że zastosowane rozwiązania nie działają dobrze.
Czynniki mają strukturę wskaźników liczbowych powiązanych z listą „poziomów”. Można to zobaczyć po przeliczeniu współczynnika na wartość liczbową. Więc:
Liczby zwrócone w ostatnim wierszu odpowiadają poziomom współczynnika.
Zauważ, że
levels()
zwraca tablicę znaków. Możesz użyć tego faktu, aby łatwo i kompaktowo konwertować współczynniki na ciągi lub liczby takie jak to:Działa to również w przypadku wartości liczbowych, pod warunkiem, że zawiniesz wyrażenie
as.numeric()
.źródło
as.character(f)
, jest lepszy zarówno pod względem czytelności, jak i wydajnościlevels(f)[as.numeric(f)]
. Jeśli chcesz być sprytny, możesz użyćlevels(f)[f]
zamiast tego. Zauważ, że konwertując współczynnik z wartościami liczbowymi, zyskujesz na przewadzeas.numeric(levels(f))[f]
np.as.numeric(as.character(f))
, Ale dzieje się tak, ponieważ musisz tylko przekonwertować poziomy na wartości liczbowe, a następnie na podzbiór.as.character(f)
jest w porządku, jak jest.Jeśli chcesz nową ramkę danych, w
bobc
której każdy wektor czynnikabobf
jest konwertowany na wektor znakowy, spróbuj tego:Jeśli następnie chcesz go przekonwertować, możesz utworzyć logiczny wektor, w którym kolumny są współczynnikami, i użyć go do selektywnego zastosowania współczynnika
źródło
Zazwyczaj tę funkcję dzielę na wszystkie moje projekty. Szybko i łatwo.
źródło
Innym sposobem jest konwersja za pomocą Apply
I lepszy (poprzedni dotyczy klasy „matrycy”)
źródło
as.data.frame(lapply(...
Aktualizacja: Oto przykład czegoś, co nie działa. Myślałem, że tak, ale myślę, że opcja stringsAsFactors działa tylko na ciągach znaków - pozostawia czynniki w spokoju.
Spróbuj tego:
Ogólnie rzecz biorąc, ilekroć masz problemy z czynnikami, które powinny być postaciami, jest jakieś
stringsAsFactors
ustawienie, które może ci pomóc (w tym ustawienie globalne).źródło
bob
na początku tworzenia (ale nie po fakcie).Lub możesz spróbować
transform
:Pamiętaj, aby umieścić każdy czynnik, który chcesz przekonwertować na postać.
Lub możesz zrobić coś takiego i zabić wszystkie szkodniki jednym ciosem:
To nie dobry pomysł, aby wpakować dane w kodzie jak ten, mogę zrobić
sapply
część osobno (właściwie, to o wiele łatwiej zrobić to w ten sposób), ale o co chodzi ... Nie sprawdzałem kod, bo Nie ma mnie w domu, więc mam nadzieję, że to zadziała! =)Takie podejście ma jednak pewną wadę ... musisz później zreorganizować kolumny, a jednocześnie
transform
możesz robić, co chcesz, ale kosztem „pisania kodu dla pieszych” ...Więc tam ... =)
źródło
Na początku ramki danych należy
stringsAsFactors = FALSE
zignorować wszystkie nieporozumienia.źródło
Jeśli użyjesz
data.table
pakietu do operacji na data.frame, problem nie będzie obecny.Jeśli masz już kolumny czynników w swoim zbiorze danych i chcesz przekonwertować je na znaki, możesz wykonać następujące czynności.
źródło
In [<-.data.table(*tmp*, sapply(bob, is.factor), : Coerced 'character' RHS to 'double' to match the column's type. Either change the target column to 'character' first (by creating a new 'character' vector length 1234 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'double' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
Łatwiej jest naprawić DF i odtworzyć DT.To działa dla mnie - w końcu wymyśliłem jedną wkładkę
źródło
Ta funkcja załatwia sprawę
źródło
Może nowsza opcja?
źródło
Powinieneś użyć,
convert
whablar
którym daje czytelną składnię kompatybilną ztidyverse
potokami:co daje ci:
źródło
Z
dplyr
załadowanym pakietemjeśli chcesz tylko zmienić
phenotype
kolumnę-konkretnie.źródło
To działa, przekształcając wszystko w znak, a następnie numerycznie w numeryczny:
Zaadaptowano z: Pobierz automatycznie typy kolumn arkusza programu Excel
źródło