¿Hay una manera más sucinta de obtener una columna de un dplyr tbl como vector, a partir de un tbl con el back-end de la base de datos (es decir, el marco / tabla de datos no puede ser subconjunto directamente)?
require(dplyr)
db <- src_sqlite(tempfile(), create = TRUE)
iris2 <- copy_to(db, iris)
iris2$Species
# NULL
Eso hubiera sido demasiado fácil, así que
collect(select(iris2, Species))[, 1]
# [1] "setosa" "setosa" "setosa" "setosa" etc.
Pero parece un poco torpe.
r
dplyr
lazy-evaluation
collect
nacnudus
fuente
fuente
collect(iris2)$Species
menos torpe?Respuestas:
Con dplyr 0.7.0, puede usar
pull
para obtener un vector de atbl
.fuente
Según el comentario de @nacnudus, parece que
pull
se implementó una función en dplyr 0.6:Para versiones anteriores de dplyr, aquí hay una función ordenada para hacer que extraer una columna sea un poco más agradable (más fácil de escribir y más fácil de leer):
Esto le permite hacer cualquiera de estos:
Resultando en...
Y también funciona bien con marcos de datos:
Una buena manera de hacer esto en v0.2 de
dplyr
:O si lo prefieres:
O si tu mesa no es demasiado grande, simplemente ...
fuente
pull <- function(x, y) { if (ncol(x) == 1) y <- 1 else y x[ , if (is.name(substitute(y))) deparse(substitute(y)) else y, drop = FALSE][[1]] }
para que pueda continuariris2 %>% pull()
magrittr
operador de exposición (%$%
) para extraer un vector de un marco de datos. es deciriris2 %>% select(Species) %>% collect() %$% Species
.pull()
se implementará en dplyr versión 0.6 github.com/tidyverse/dplyr/commit/…También puede usar lo
unlist
que me parece más fácil de leer porque no necesita repetir el nombre de la columna o especificar el índice.fuente
unlist
es precisamente lo que necesitaba. ¡Gracias!unlist
También puede extraer valores de múltiples columnas (combinando todos los valores en un solo vector), mientras quedplyr::pull
está limitado a una sola columna.Usaría la
extract2
función de conveniencia demagrittr
:fuente
collect()
entreselect
yextract2
?use_series(Species)
es quizás aún más legible. Gracias por alertarme sobre estas funciones, hay varias otras útiles de donde provienen.Probablemente escribiría:
Dado que dplyr está diseñado para trabajar con tbls de datos, no hay mejor manera de obtener una sola columna de datos.
fuente
group_by(column) %.% tally()
drop = TRUE
paradplyr::select
sería sorprendente para los muchos casos de uso en los que realmente necesitamos extraer los vectores.@ Luke1018 propuso esta solución en uno de los comentarios:
Por ejemplo:
Pensé que merecía su propia respuesta.
fuente
tibble(x = 1:10, y = letters[1:10]) %>% select_("x") %>% unlist()
y también podría agregar otro%>% unname()
al final si lo desea, pero para mis propósitos no he encontrado que el último eslabón de la cadena de tuberías sea necesario. También puede especificaruse.names = FALSE
en elunlist()
comando, que hace lo mismo que también se agregaunname()
a la cadena de tuberías.pull
comando ahora. Mi solución fue escrita antes de ladplyr
versión 0.6.%$%
funciona en cualquier lista, mientraspull()
que noSi está acostumbrado a usar corchetes para indexar, otra opción es simplemente ajustar el enfoque de indexación habitual en una llamada a deframe () , por ejemplo:
Eso y pull () son dos formas bastante buenas de obtener una columna tibble.
fuente