ver tablas ordenar nombres mover filtros filas eliminar datos data columnas agrupar r

tablas - ¿Cómo puedo decirle a select() en dplyr que la cadena que está viendo es un nombre de columna en un marco de datos?



tablas en r (7)

Intenté buscar pero no encontré una respuesta a esta pregunta.

Intento utilizar la instrucción select en dplyr pero tengo problemas cuando intento enviar cadenas. Mi pregunta es, ¿cómo le digo a select () que la cadena que está viendo es un nombre de columna en el marco de datos?

por ejemplo, esto funciona bien

select(df.main.scaled, var1, var3) select(df.main.scaled, var2, var4)

Pero esto no funciona:

select(df.main.scaled, names.gens[i,1], names.gens[i,2])

dónde

> names.genx <- c("var1","var2") > names.geny <- c("var3","var4") > names.gens <- cbind(names.genx, names.geny) > names.gens names.genx names.geny [1,] "var1" "var3" [2,] "var2" "var4"

Para que quede claro, todas las cadenas en names.gens son nombres de columna en el marco de datos.

Gracias.


En versiones más recientes de dplyr, esto es posible en select con one_of , como en

my_cols <- c(''mpg'', ''disp'') mtcars %>% select(one_of(my_cols))


Hay una solución en dplyr 0.1.2 usando expresiones regulares y coincidencias (consulte el comentario de hadley a continuación para obtener información sobre soporte directo en versiones futuras). Una expresión regular como ^(x1|x2|x3)$ coincide con los nombres de las variables exactas, por lo que solo tenemos que construir dicha expresión a partir de un vector con nombres de variables. Aquí está el código

# load libraries library(dplyr) library(stringr) # create data.frame df = data.frame( x = rep(0,5), y = 1, var = 2, another_var = 5, var.4 = 6 ) # function to construct reg exp from vector with variable names varlist = function(x) { x = str_c(''^('',paste(x, collapse=''|''),'')$'') x = str_replace_all(x,''//.'',''////.'') return(x) } # select variables based on vector of variable names vars = c(''y'',''another_var'',''var.4'') df %>% select(matches(varlist(vars)))


Lo descubrí a través de prueba y error. Si alguien tiene curiosidad, hizo algo como esto:

lapply(names.gens, as.name) select(df.main.scaled, eval(names.gens[[i]]), eval(names.gens[[i+someindex]]))


Me encontré con esto y pensé que debería mencionar que esto se ha resuelto en las versiones más nuevas de dplyr.

R> iris %>% select(Species, Petal.Length) %>% head(3) Species Petal.Length 1 setosa 1.4 2 setosa 1.4 3 setosa 1.3 R> iris %>% select(''Species'', ''Petal.Length'') %>% head(3) Error in abs(ind[ind < 0]) : non-numeric argument to mathematical function R> iris %>% select(get(''Species''), get(''Petal.Length'')) %>% head(3) Species Petal.Length 1 setosa 1.4 2 setosa 1.4 3 setosa 1.3 R> s <- ''Species'' R> p <- ''Petal.Length'' R> iris %>% select(get(s), get(p)) %>% head(3) Species Petal.Length 1 setosa 1.4 2 setosa 1.4 3 setosa 1.3


Puede usar get() para obtener el objeto nombrado por la cadena en el entorno actual. Asi que:

myTest = data_frame( var1 = 1, var2 = 2, var3 = 3, var4 = 4) i = 1 myTest %>% select_(.dots = c(names.gens[i,1], names.gens[i,2]) %>% unname)


Select parece funcionar con los índices de columnas (dplyr 0.2), de modo que simplemente haga coincidir los nombres que desee con su índice y utilícelos para seleccionar las columnas.

myCols <- c("mpg","disp") colNums <- match(myCols,names(mtcars)) mtcars %>% select(colNums)


[Editar - algunos de los siguientes están desactualizados con el lanzamiento de dplyr 0.7 - ver here ]

La pregunta es sobre la diferencia entre la evaluación estándar y la evaluación no estándar.

tl; dnr: puede usar la contraparte ''evaluación estándar'' de dplyr::select , que es dplyr::select_ .

Esto le permite proporcionar nombres de columna como variables que contienen cadenas:

dplyr::select_(df.main.scaled, names.gens[i,1], names.gens[i,2])

Aquí hay muchos más detalles que intentan explicar cómo funciona esto:

Evaluación no estándar y la función de selección en dplyr

La evaluación no estándar es la evaluación del código de formas no estándar. A menudo, esto significa capturar expresiones antes de que se evalúen y evaluarlas en un entorno diferente (contexto / alcance) a lo normal. Cuando proporciona dplyr::select con los nombres de columna sin comillas, dplyr está utilizando una evaluación no estándar para interpretarlos como columnas.

Ejemplos de uso de dplyr :: select

Supongamos que tenemos el siguiente marco de datos:

df <- tibble::data_frame(a = 1:5, b = 6:10, c = 11:15, d = 16:20)

Un ejemplo simple de la instrucción select es la siguiente:

r <- dplyr::select(df, a, b)

Este es un ejemplo de NSE porque a y b no son variables que existen en el entorno global. En lugar de buscar ayb en el espacio de nombre global, dplyr::select dirige a R para buscar las variables a y b en el contexto del marco de datos df . Puedes pensar que el entorno es un poco como una lista, y a y b como claves. Así que lo siguiente es un poco como decirle a R que busque df$a y df$b

Los argumentos de función en R son promises que no se evalúan inmediatamente. Se pueden capturar como expresiones y luego ejecutar en un entorno diferente.

Esto está bien si sabemos que queremos seleccionar las columnas b con anticipación. Pero, ¿qué ocurre si estas columnas se desconocen de antemano y se mantienen en una variable?

columns_to_select <- c("a", "b")

Lo siguiente no funciona:

dplyr::select(df, columns_to_select)

Este error nos dice que no hay una columna llamada ''columns_to_select'' en el marco de datos. El argumento columns_to_select se ha evaluado en el contexto del marco de datos, por lo que R ha intentado hacer algo como df$columns_to_select , y ha encontrado que la columna no existe.

¿Cómo arreglamos esto?

Las funciones Tidyverse siempre proporcionan una ''escotilla de escape'' que le permite sortear esta limitación. La viñeta dplyr dice: "Todas las funciones en dplyr que usan NSE también tienen una versión que usa SE. El nombre de la versión SE es siempre el nombre NSE con un _ al final. ''

¿Qué significa esto?

Podríamos intentar lo siguiente, pero descubrimos que no funciona:

# Does not work r <-dplyr::select_(df, columns_to_select)

A diferencia de capturar el argumento columns_to_select a la función select_ e interpretarlo como un nombre de columna, columns_to_select se evalúa de forma estándar, resolviendo c("a", "b") .

Eso es lo que queremos, excepto que cada argumento para select_ es una sola columna, y acabamos de proporcionar un vector de caracteres de longitud dos para representar una sola columna.

Por lo tanto, el código anterior devuelve un tibble con una sola columna, a, que no es lo que queríamos. (Solo se usa el primer elemento - "a" en el vector de caracteres, todo lo demás se ignora).

Una solución a este problema es la siguiente, pero supone que columns_to_select contiene exactamente dos elementos:

col1 <- columns_to_select[1] col2 <- columns_to_select[2] r <- dplyr::select_(df,col1, col2)

¿Cómo generalizamos esto al caso en que columns_to_select puede tener un número arbitrario de elementos?

La solución es usar el argumento .dots opcional.

dplyr::select_(df, .dots=columns_to_select)

Esto tiene alguna explicación

En R, el ... constructo permite la creación de funciones con un número variable (arbitrario) de argumentos. El ... está disponible dentro de la función y permite que el cuerpo de la función acceda a todos los argumentos. Ver también here .

Un ejemplo muy simple es el siguiente:

addition <- function(...) { args <- list(...) sum(unlist(args)) } r <- addition(1,2,3)

Sin embargo, esto no nos ayuda de inmediato aquí. En realidad, ya está implementado en la función select_ y simplemente nos permite proporcionar un número arbitrario de nombres de columna como argumentos, por ejemplo, select_(df, "a", "b", "c", "d") .

Lo que necesitamos es un mecanismo que sea similar a ... , pero que nos permita pasar algo así como ... a la función como un único argumento. Esto es exactamente lo que hace .dots .

Tenga en cuenta que .dots no es proporcionado por select , ya que está diseñado para ser utilizado de forma interactiva.