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.

Timm S.
fuente
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.

joran
fuente
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
60

Puedes probar:

select(data, matches("search_string"))

Es más general que contains: puede usar expresiones regulares (por ejemplo "one_string|or_the_other").

Para obtener más ejemplos, consulte: http://rpackages.ianhowson.com/cran/dplyr/man/select.html .

Piotr Migdal
fuente
1
mejor desde que admite expresiones
regulares
El enlace está caído ahora
pratikpc
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
Jilber Urbina
fuente
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).

Boern
fuente
5
Para un vector de nombres de columna conocidos, useselect(df, one_of(array_of_colnames))
AlexR