Filtruj wiele wartości w kolumnie łańcuchowej w dplyr
Mam {[3] } z danymi znakowymi w jednej z kolumn.
Chciałbym filtrować wiele opcji w data.frame
z tej samej kolumny. Czy jest na to łatwy sposób, którego mi brakuje?
Przykład:
data.frame
name = dat
days name
88 Lynn
11 Tom
2 Chris
5 Lisa
22 Kyla
1 Tom
222 Lynn
2 Lynn
Chciałbym odfiltrować Tom
i Lynn
na przykład.
Kiedy robię:
target <- c("Tom", "Lynn")
filt <- filter(dat, name == target)
Dostaję ten błąd:
longer object length is not a multiple of shorter object length
3 answers
Potrzebujesz %in%
zamiast ==
:
library(dplyr)
target <- c("Tom", "Lynn")
filter(dat, name %in% target) # equivalently, dat %>% filter(name %in% target)
Produkuje
days name
1 88 Lynn
2 11 Tom
3 1 Tom
4 222 Lynn
5 2 Lynn
Aby zrozumieć dlaczego, zastanów się, co się tutaj dzieje:
dat$name == target
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Zasadniczo przeliczamy dwie długości target
wektora cztery razy, aby dopasować długość dat$name
. Innymi słowy, robimy:
Lynn == Tom
Tom == Lynn
Chris == Tom
Lisa == Lynn
... continue repeating Tom and Lynn until end of data frame
W tym przypadku nie otrzymujemy błędu, ponieważ podejrzewam, że twoja ramka danych ma inną liczbę wierszy, które nie pozwalają na recykling, ale próbka, którą podasz, tak (8 wierszy). Jeśli próbka gdyby miał nieparzystą liczbę wierszy, otrzymałbym ten sam błąd co Ty. Ale nawet gdy recykling działa, to wyraźnie nie jest to, czego chcesz. Zasadniczo twierdzenie dat$name == target
jest równoważne stwierdzeniu:
Return
TRUE
dla każdej nieparzystej wartości równej " Tom "lub każdej parzystej wartości równej "Lynn".
Tak się składa, że ostatnia wartość w przykładowej ramce danych jest parzysta i równa "Lynn", stąd ta TRUE
powyżej.
Dla kontrastu, dat$name %in% target
says:
Bardzo różne. Oto wynik:Dla każdej wartości w
dat$name
, sprawdź, czy istnieje wtarget
.
[1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE
Zauważ, że twój problem nie ma nic wspólnego z dplyr
, tylko z niewłaściwym użyciem ==
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-03 15:01:36
Korzystanie z pakietu base
:
df <- data.frame(days = c(88, 11, 2, 5, 22, 1, 222, 2), name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn"))
# Three lines
target <- c("Tom", "Lynn")
index <- df$name %in% target
df[index, ]
# One line
df[df$name %in% c("Tom", "Lynn"), ]
Wyjście:
days name
1 88 Lynn
2 11 Tom
6 1 Tom
7 222 Lynn
8 2 Lynn
Używając sqldf
:
library(sqldf)
# Two alternatives:
sqldf('SELECT *
FROM df
WHERE name = "Tom" OR name = "Lynn"')
sqldf('SELECT *
FROM df
WHERE name IN ("Tom", "Lynn")')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 10:10:34
Można to osiągnąć za pomocą pakietu dplyr, który jest dostępny w CRAN. Prosty sposób na osiągnięcie tego:
Install
dplyr
package.library(dplyr) df<- select(filter(dat,name=='tom'| name=='Lynn',c('days','name))
Wyjaśnienie:
Tak więc, po pobraniu dplyr, tworzymy nową ramkę danych za pomocą dwóch różnych funkcji z tego pakietu:
Filter: pierwszy argument to ramka danych; drugi argument to warunek, według którego chcemy ją podzestawić. Rezultatem jest cała ramka danych tylko te rzędy, które chcieliśmy. select: pierwszy argument to ramka danych; drugi argument to nazwy kolumn, które chcemy z niej wybrać. Nie musimy używać funkcji names (), a nawet nie musimy używać cudzysłowów. Po prostu wymieniamy nazwy kolumn jako obiekty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-21 19:49:04