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
Author: smci, 2014-09-03

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:

Dla każdej wartości w dat$name, sprawdź, czy istnieje w target.

Bardzo różne. Oto wynik:
[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 ==.

 126
Author: BrodieG,
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")')
 7
Author: mpalanco,
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:

  1. Install dplyr package.

  2. 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.

 6
Author: AutomationNerd,
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