vacio tablas studio seleccionar matrices filtrar filas datos crear columnas agrupar r dplyr

tablas - Agrupe por columnas mĂșltiples en dplyr, usando entrada de vector de cadena



seleccionar filas en r (8)

Dado que esta pregunta se publicó, dplyr agregó versiones con ámbito de group_by ( documentación aquí ). Esto le permite usar las mismas funciones que usaría con select , así:

data = data.frame( asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE), a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE), value = rnorm(100) ) # get the columns we want to average within columns = names(data)[-3] library(dplyr) df1 <- data %>% group_by_at(vars(one_of(columns))) %>% summarize(Value = mean(value)) #compare plyr for reference df2 <- plyr::ddply(data, columns, plyr::summarize, value=mean(value)) table(df1 == df2, useNA = ''ifany'') ## TRUE ## 27

El resultado de su pregunta de ejemplo es el esperado (consulte la comparación con plyr anterior y el resultado a continuación):

# A tibble: 9 x 3 # Groups: asihckhdoydkhxiydfgfTgdsx [?] asihckhdoydkhxiydfgfTgdsx a30mvxigxkghc5cdsvxvyv0ja Value <fctr> <fctr> <dbl> 1 A A 0.04095002 2 A B 0.24943935 3 A C -0.25783892 4 B A 0.15161805 5 B B 0.27189974 6 B C 0.20858897 7 C A 0.19502221 8 C B 0.56837548 9 C C -0.22682998

Tenga en cuenta que dado que dplyr::summarize solo dplyr::summarize una capa de agrupamiento a la vez, todavía tiene actividad en el tibble resultante (que a veces puede capturar personas por sorpresa más adelante). Si desea estar absolutamente seguro frente a comportamientos de agrupación inesperados, siempre puede agregar %>% ungroup a su canalización después de resumir.

Intento transferir mi comprensión de plyr a dplyr, pero no puedo entender cómo agrupar por varias columnas.

# make data with weird column names that can''t be hard coded data = data.frame( asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE), a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE), value = rnorm(100) ) # get the columns we want to average within columns = names(data)[-3] # plyr - works ddply(data, columns, summarize, value=mean(value)) # dplyr - raises error data %.% group_by(columns) %.% summarise(Value = mean(value)) #> Error in eval(expr, envir, enclos) : index out of bounds

¿Qué me falta para traducir el ejemplo plyr en una sintaxis dplyr-esque?

Edición 2017 : Dplyr se ha actualizado, por lo que una solución más simple está disponible. Ver la respuesta seleccionada actualmente.


El soporte para esto en dplyr es actualmente bastante débil, eventualmente creo que la sintaxis será algo así como:

df %.% group_by(.groups = c("asdfgfTgdsx", "asdfk30v0ja"))

Pero eso probablemente no estará allí por un tiempo (porque necesito pensar en todas las consecuencias).

Mientras tanto, puedes usar regroup() , que toma una lista de símbolos:

library(dplyr) df <- data.frame( asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE), a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE), value = rnorm(100) ) df %.% regroup(list(quote(asihckhdoydk), quote(a30mvxigxkgh))) %.% summarise(n = n())

Si tiene un vector de caracteres de nombres de columna, puede convertirlos a la estructura correcta con lapply() y as.symbol() :

vars <- setdiff(names(df), "value") vars2 <- lapply(vars, as.symbol) df %.% regroup(vars2) %.% summarise(n = n())


Funciona si le pasa los objetos (bueno, no lo es, pero ...) en lugar de como un vector de caracteres:

df %.% group_by(asdfgfTgdsx, asdfk30v0ja) %.% summarise(Value = mean(value)) > df %.% + group_by(asdfgfTgdsx, asdfk30v0ja) %.% + summarise(Value = mean(value)) Source: local data frame [9 x 3] Groups: asdfgfTgdsx asdfgfTgdsx asdfk30v0ja Value 1 A C 0.046538002 2 C B -0.286359899 3 B A -0.305159419 4 C A -0.004741504 5 B B 0.520126476 6 C C 0.086805492 7 B C -0.052613078 8 A A 0.368410146 9 A B 0.088462212

donde df era tu data .

?group_by dice:

...: variables to group by. All tbls accept variable names, some will also accept functons of variables. Duplicated groups will be silently dropped.

que interpreto que significa no las versiones de los nombres de los personajes, sino cómo se referiría a ellos en foo$bar ; bar no está citada aquí. O cómo te referirías a las variables en una fórmula: foo ~ bar .

@Arun también menciona que puedes hacer:

df %.% group_by("asdfgfTgdsx", "asdfk30v0ja") %.% summarise(Value = mean(value))

Pero no se puede pasar algo que no se ha evaluado no es un nombre de una variable en el objeto de datos.

Supongo que esto se debe a los métodos internos que Hadley está usando para buscar las cosas que pasa a través del ... argumento.


Hasta que dplyr tenga soporte completo para los argumentos de cadena, quizás esta esencia sea útil:

https://gist.github.com/skranz/9681509

Contiene un montón de funciones de envoltura como s_group_by, s_mutate, s_filter, etc. que usan argumentos de cadena. Puede mezclarlos con las funciones dplyr normales. Por ejemplo

cols = c("cyl","gear") mtcars %.% s_group_by(cols) %.% s_summarise("avdisp=mean(disp), max(disp)") %.% arrange(avdisp)


La especificación de cadenas de columnas en dplyr ahora se admite a través de variantes de las funciones dplyr con nombres que terminan en un guión bajo. Por ejemplo, correspondiente a la función group_by hay una función group_by_ que puede tomar argumentos de cadena. Esta viñeta describe la sintaxis de estas funciones en detalle.

El siguiente fragmento resuelve limpiamente el problema que @sharoz planteó originalmente (tenga en cuenta la necesidad de escribir el argumento .dots ):

# Given data and columns from the OP data %>% group_by_(.dots = columns) %>% summarise(Value = mean(value))

(Tenga en cuenta que dplyr ahora usa el operador %>% y %.% Está en desuso).


Para escribir el código completo, aquí hay una actualización de la respuesta de Hadley con la nueva sintaxis:

library(dplyr) df <- data.frame( asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE), a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE), value = rnorm(100) ) # Columns you want to group by grp_cols <- names(df)[-3] # Convert character vector to list of symbols dots <- lapply(grp_cols, as.symbol) # Perform frequency counts df %>% group_by_(.dots=dots) %>% summarise(n = n())

salida:

Source: local data frame [9 x 3] Groups: asihckhdoydk asihckhdoydk a30mvxigxkgh n 1 A A 10 2 A B 10 3 A C 13 4 B A 14 5 B B 10 6 B C 12 7 C A 9 8 C B 12 9 C C 10


Un caso (pequeño) que falta en las respuestas aquí, que quería hacer explícito, es cuando las variables para agrupar se generan dinámicamente a mitad de camino en una canalización:

library(wakefield) df_foo = r_series(rnorm, 10, 1000) df_foo %>% # 1. create quantized versions of base variables mutate_each( funs(Quantized = . > 0) ) %>% # 2. group_by the indicator variables group_by_( .dots = grep("Quantized", names(.), value = TRUE) ) %>% # 3. summarize the base variables summarize_each( funs(sum(., na.rm = TRUE)), contains("X_") )

Esto básicamente muestra cómo usar grep junto con group_by_(.dots = ...) para lograr esto.


data = data.frame( my.a = sample(LETTERS[1:3], 100, replace=TRUE), my.b = sample(LETTERS[1:3], 100, replace=TRUE), value = rnorm(100) ) group_by(data,newcol=paste(my.a,my.b,sep="_")) %>% summarise(Value=mean(value))