Seleccionar columnas según la coincidencia de cadenas - dplyr :: select


83

Tengo un marco de datos ("datos") con muchas, muchas columnas. Algunas de las columnas contienen una determinada cadena ("search_string").

¿Cómo puedo usar dplyr::select()para darme un subconjunto que incluya solo las columnas que contienen la cadena?

Lo intenté:

# columns as boolean vector
select(data, grepl("search_string",colnames(data)))

# columns as vector of column names names 
select(data, colnames(data)[grepl("search_string",colnames(data))]) 

Ninguno de los dos funciona.

Sé que select()acepta vectores numéricos como sustituto de columnas, por ejemplo:

select(data,5,7,9:20)

Pero no sé cómo obtener un vector numérico de columnas IDa partir de mi grepl()expresión.


Vea también esta respuesta SO para múltiples cadenas y coincidencias: stackoverflow.com/q/29018292/3871924
agenis

Respuestas:


114

Dentro del mundo dplyr , intente:

select(iris,contains("Sepal"))

Consulte la sección Selección de ?selectpara numerosos otros ayudantes les gusta starts_with, ends_withetc.


2
Tenga en cuenta que puede despegarse de esto con bastante facilidad, ya que al tratar de evitar la expresión regular, la expresión regular regresa para morderlo, por ejemplo: select(iris, contains(".") )No estoy seguro de cómo se supone que debe pasar fixed=TRUEpara forzar la búsqueda de un real"."
thelatemail

1
@thelatemail Eso se siente como un descuido, ya sea en el código o en los documentos (es decir, estamos asumiendo fixed = TRUEo el equivalente). dplyr es todavía bastante joven.
joran

@thelatemail ¡Ups! ¡Yo tambien!
joran

6
Bueno, ese es un comienzo bastante pobre para mi carrera de github entonces. ¡Próximamente "Cerrar como duplicado"!
thelatemail

1
@MattBannert vea la solución que proporcioné
Boern


30

No es necesario usar selectsolo usar [en su lugar

data[,grepl("search_string", colnames(data))]

Probemos con el irisconjunto de datos

>iris[,grepl("Sepal", colnames(iris))]
  Sepal.Length Sepal.Width
1          5.1         3.5
2          4.9         3.0
3          4.7         3.2
4          4.6         3.1
5          5.0         3.6
6          5.4         3.9

6
@arumbay dplyres un panceum, incluso cuando puede hacerlo base, la sintaxis estándar no es tan agradable / legible / componible: vea mi respuesta .
Piotr Migdal

20

Según la respuesta de Piotr Migdals, quiero ofrecer una solución alternativa que permita la posibilidad de un vector de cadenas:

myVectorOfStrings <- c("foo", "bar")
matchExpression <- paste(myVectorOfStrings, collapse = "|")
# [1] "foo|bar"
df %>% select(matches(matchExpression))

Haciendo uso del ORoperador regex ( |)

ATENCIÓN : Si realmente tiene un vector simple de nombres de columna (y no necesita el poder de RegExpression), consulte el comentario debajo de esta respuesta (ya que es la solución más limpia).


5
Para un vector de nombres de columna conocidos, useselect(df, one_of(array_of_colnames))
AlexR
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.