2014-11-11 10 views
14

È possibile utilizzare select in dplyr con un vettore logico?dplyr select using logical

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

Errore nei nomi (sel) [senza nome] < - sel [senza nome]: AN non sono ammessi nelle assegnazioni indicizzate

Indici lavorano select(dat,(1:ncol(dat))[isNum]) quindi perché non una logica ?

Edit 1:

Quando ho visto le funzioni di supporto per selezionare come starts_with select(dat,starts_with("m")) pensai che sarebbe lavorare con una logica

Edit 2:

select(dat, which(isNum)) funziona

+2

Forse un [argomento di 'dplyr 0.3.1'] (https://github.com/hadley/dplyr/issues/497): "In generale, qual è il modo migliore per filtrare le colonne per alcune condizioni booleane in' dplyr'? " – Henrik

+1

Penso che dovresti postare 'select (dat, which (isNum))' come risposta (e anche accettarlo se sembra la soluzione migliore) –

risposta

10

Le mie risposte sarebbero:

  • no ("Si può selezionare in dplyr essere utilizzato con un vettore logica?")

prove: (1) il vostro esempio, (2) la pagina di aiuto:

. ..: elenco separato da virgole di espressioni non quotate. È possibile trattare i nomi delle variabili come se fossero posizioni. Utilizzare i valori positivi per selezionare le variabili; utilizzare valori negativi per eliminare le variabili.

Non dice nulla sui vettori logici. Scusate.

  • Non so ("perché non è logico?") - "solo perché" (non credo che nessuno, a parte lo sviluppatore, possa davvero rispondere a questa domanda). Si potrebbe mettere in una richiesta di funzionalità ...

E 'un po' goffo, ma

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

opere (notare che è necessario la variante select_ per consentire l'utilizzo di un vettore di carattere). Ma il buon vecchio stile

subset(dat,select=isNum) 

sembra funzionare bene anche (a meno che non riesce a giocare bene con dplyr in qualche altro modo che non ho pensato).

Se si guarda il codice di dplyr:::starts_with, si può vedere che restituisce un vettore di posizioni, non è un vettore logica

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) 
} 

Stavo per suggerire che si tenta di modificare questa funzione per creare un is_numeric equivalente, ma non capisco abbastanza bene la magia sottostante ...

16

Come Ben suggerito:

select(dat, which(isNum))

+0

Questo è davvero utile perché possiamo mettere 'which' davanti a qualsiasi appropriato costruzione logica per restituire i numeri di colonna. –

2

Come indicato molto chiaramente in altre risposte, la risposta alla tua domanda specifica è non. Non è possibile utilizzare un vettore logico in dplyr::select().

Tuttavia, nelle versioni più recenti di dplyr (v> = 0.5.0) c'è una nuova funzione che supporta l'uso di una funzione predicato da applicare alle colonne o un vettore logica: select_if().

Utilizzando select_if con una funzione predicato, il tuo esempio potrebbe essere semplificata come segue:

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

Ma, è anche possibile utilizzare select_if con un vettore logico. Questo risolve più direttamente il vostro caso d'uso di cui sopra, che sarebbe simile al seguente:

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