W ramce danych R zakodowanej poniżej chciałbym zamienić wszystkie czasy, które B
pojawiają się na b
.
junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12])
colnames(junk) <- c("nm", "val")
to zapewnia:
nm val
1 A a
2 B b
3 C c
4 D d
5 A e
6 B f
7 C g
8 D h
9 A i
10 B j
11 C k
12 D l
Moja pierwsza próba polegała na użyciu a for
i if
takich stwierdzeń:
for(i in junk$nm) if(i %in% "B") junk$nm <- "b"
ale jak na pewno widzisz, zastępuje to WSZYSTKIE wartości junk$nm
z b
. Rozumiem, dlaczego tak się dzieje, ale nie wydaje mi się, aby zastępował tylko te przypadki złomu $ nm, w których była pierwotna wartość B
.
UWAGA: udało mi się rozwiązać problem, gsub
ale w interesie nauki RI nadal chciałbym wiedzieć, jak uzyskać moje oryginalne podejście do pracy (jeśli jest to możliwe)
Odpowiedzi:
Łatwiej przekonwertować nm na znaki, a następnie wprowadzić zmianę:
EDYCJA: A jeśli rzeczywiście musisz zachować nm jako czynniki, dodaj to na końcu:
źródło
kolejny przydatny sposób zastępowania wartości
źródło
Krótka odpowiedź brzmi:
Spójrz na wektory indeksu w Wprowadzenie do języka R (jeśli jeszcze tego nie czytałeś).
EDYTOWAĆ. Jak zauważono w komentarzach, to rozwiązanie działa dla wektorów znaków, więc nie działa na danych.
Najlepszym sposobem jest zmiana poziomu:
źródło
c("B","C")
. Robijunk$nm[junk$nm == "B"]
to lepszy sposób.b
do współczynnika nm. Wersja diliopa jest w rzeczywistości lepsza, jeśli chcesz pracować z postaciami, a nie czynnikami. (Zawsze myśl najpierw o typie, jaki mają twoje zmienne!)%in%
i==
jestNA
obsługa:c(1,2,NA)==1
daje,TRUE, FALSE, NA
alec(1,2,NA) %in% 1
dajeTRUE, FALSE, FALSE
. I tak zapomniałem sprawdzić czy to działa: /Ponieważ dane, które pokazujesz, są czynnikami, komplikuje to trochę sprawę. Odpowiedź @ diliopa rozwiązuje problem, przekształcając
nm
ją w zmienną znakową . Aby wrócić do pierwotnych czynników, wymagany jest kolejny krok.Alternatywą jest manipulowanie istniejącymi poziomami czynnika.
Jest to dość proste i często zapominam, że istnieje funkcja zastępująca
levels()
.Edycja: jak zauważył @Seth w komentarzach, można to zrobić w jednej linijce, bez utraty przejrzystości:
źródło
levels()
. A co z jednym wkłademjunk <- within(junk, levels(nm)[levels(nm)=="B"] <- "b")
?Najłatwiej to zrobić w jednym poleceniu, używając
which
polecenia, a także nie trzeba zmieniać współczynników na charakter, wykonując następujące czynności:źródło
Utworzyłeś zmienną czynnikową w programie,
nm
więc musisz albo tego unikać, albo dodać dodatkowy poziom do atrybutów współczynnika. Należy również unikać używania<-
w argumentach funkcji data.frame ()Opcja 1:
Opcja 2:
źródło
data.frame
?b
, jak najwyższym poziomie, wystarczy zmienić poziom, który jestB
dob
.a <- data.frame(x<-1:10)
. Nazwa jego kolumny nie jest,x
ale raczej niechlujnax....1.10
. Lepiej użyć data.frame (x = 1:10). Wtedy wiesz, jaka jest nazwa twojej kolumny.predict()
które będzie narzekać, jeśli poziomy czynników w nowych danych nie będą pasować do tych, które były używane do dopasowania modelu. Czystsze na dłuższą metę, aby poprawnie sformatować dane, niż polegać na skrótach. Zgadzam się, że może być łatwiej nie robić tego czynnikiem, ale jeśli już nim jest, lub musi nim być do jakiegoś ćwiczenia modelarskiego ...Jeśli pracujesz ze zmiennymi znakowymi (zwróć uwagę, że
stringsAsFactors
tutaj jest fałsz), możesz użyć zamiany:źródło
Wywołaj tę funkcję za pomocą poniższej linii.
źródło