2014-11-11 16 views
14

Czy można używać w wektorze logicznym?dplyr wybrać przy użyciu logicznej

dat <- tbl_df(mtcars) 
isNum <- sapply(dat, is.numeric) 
select(dat, isNum) 
select(dat, isNum) 

Błąd w nazwie (SEL) [nienazwany] < - sel [nienazwany]: agencje krajowe nie są dozwolone w zadaniach indeksowaną

Indeksy pracować select(dat,(1:ncol(dat))[isNum]) więc dlaczego nie logiczne ?

Edit 1:

Kiedy zobaczyłem funkcji pomocniczych dla select jak starts_with select(dat,starts_with("m")) Przypuszczałem będą pracować z logicznym

Edit 2:

select(dat, which(isNum)) pracuje

+2

ewentualnie [temat dla 'dplyr 0.3.1'] (https://github.com/hadley/dplyr/issues/497): "W ogóle, jaki jest najlepszy sposób filtrowania kolumn według jakiegoś warunku boolowskiego w' dplyr'? " – Henrik

+1

Myślę, że powinieneś napisać 'select (dat, which (isNum))' jako odpowiedź (a nawet zaakceptować, jeśli wydaje się najlepszym rozwiązaniem) –

Odpowiedz

10

Moje odpowiedzi to:

  • nie ("można wybrać w dplyr być stosowany z logicznym wektora?")

dowody: (1) Twój przykład, (2) strona help:

. ..: rozdzielana przecinkami lista niecytowanych wyrażeń. Można traktować zmienne o nazwach , tak jak są pozycjami. Użyj wartości dodatnich , aby wybrać zmienne; użyj wartości ujemnych, aby upuścić zmienne.

Nic nie mówi o wektorach logicznych. Przepraszam.

  • Nie wiem ("dlaczego nie logiczne?") - "tylko dlatego" (nie sądzę, by ktokolwiek poza programistą mógł naprawdę odpowiedzieć na to pytanie). można umieścić we wniosku fabularnego ...

To trochę niezgrabne, ale

select_(dat,.dots=names(isNum)[isNum]) 

prace (zauważ, że trzeba wariant select_ aby umożliwić stosując wektor znaków). Ale dobry staromodny

subset(dat,select=isNum) 

wydaje się działać zbyt dobrze (o ile nie jest on grać ładnie z dplyr w jakiś inny sposób nie myślałem o).

Jeśli spojrzeć na kodzie dplyr:::starts_with, widać, że zwraca wektor pozycjach, a nie logiczną wektor

function (vars, match, ignore.case = TRUE) 
{ 
    stopifnot(is.string(match), !is.na(match), nchar(match) > 
     0) 
    if (ignore.case) 
     match <- tolower(match) 
    n <- nchar(match) 
    if (ignore.case) 
     vars <- tolower(vars) 
    which(substr(vars, 1, n) == match) 
} 

miałem zamiar zaproponować, aby spróbować zmodyfikować tę funkcję, aby stworzyć is_numeric odpowiednik, ale ja nie rozumiem podstawowej magii wystarczająco dobrze ...

16

Jako Ben zaproponował:

select(dat, which(isNum))

+0

Jest to bardzo użyteczne, ponieważ możemy umieścić "który" przed jakimkolwiek odpowiednim konstrukcja logiczna do zwracania numerów kolumn. –

2

Jak stwierdzono bardzo wyraźnie w innych odpowiedzi, odpowiedź na Twoje pytanie jest nr. Nie można użyć wektora logicznego w dplyr::select().

Jednak w nowszych wersjach dplyr (v> = 0.5.0) pojawiła się nowa funkcja, która umożliwia korzystanie z funkcji orzeczenie, które należy stosować do kolumn lub logicznej wektora: select_if().

Korzystanie select_if z funkcji orzecznika, Twój przykład można uprościć następująco:

tbl_df(mtcars) %>% dplyr::select_if(is.numeric) 

Ale można też użyć select_if z logicznym wektorze. Ten bardziej bezpośrednio odnosi przypadku użycia powyżej, które mogłyby wyglądać następująco:

dat <- tbl_df(mtcars) 
isNum <- sapply(dat, is.numeric) 
select_if(dat, isNum) 
Powiązane problemy