2010-02-14 18 views
288

Tengo algunos problemas con los espacios en blanco iniciales y finales en un data.frame. Por ejemplo, me gusta echar un vistazo a una específica row en un data.frame basado en una determinada condición:¿Cómo se recortan los espacios en blanco iniciales y finales en R?

> myDummy[myDummy$country == c("Austria"),c(1,2,3:7,19)] 

[1] codeHelper  country  dummyLI dummyLMI  dummyUMI  
[6] dummyHInonOECD dummyHIOECD dummyOECD  
<0 rows> (or 0-length row.names) 

Me preguntaba por qué no he tenido el resultado esperado ya que el país Austria, obviamente existido en mi data.frame. Después de mirar a través de mi historial de códigos y tratando de averiguar lo que salió mal Traté:

> myDummy[myDummy$country == c("Austria "),c(1,2,3:7,19)] 
    codeHelper country dummyLI dummyLMI dummyUMI dummyHInonOECD dummyHIOECD 
18  AUT Austria  0  0  0    0   1 
    dummyOECD 
18   1 

Todo lo que han cambiado en el comando es un espacio en blanco adicional después de Austria.

Surgen obviamente otros problemas molestos. Por ejemplo, cuando me gusta fusionar dos marcos en función de la columna del país. Uno data.frame usa "Austria ", mientras que el otro marco tiene "Austria". La coincidencia no funciona.

  1. ¿Hay una buena manera de 'mostrar' el espacio en blanco en mi pantalla para que yo sepa el problema?
  2. ¿Y puedo eliminar el espacio en blanco inicial y final en R?

Hasta ahora he utilizado para escribir un simple script Perl que elimina los espacios en blanco, pero sería bueno si de alguna manera puedo hacerlo dentro R.

+1

Acabo de ver que 'sub()' usa la notación 'Perl' también. Lo siento por eso. Voy a tratar de usar la función. Pero para mi primera pregunta aún no tengo una solución. – mropa

+4

Como hadley señaló que esta expresión regular "^ \\ s + | \\ s + $" identificará los espacios en blanco iniciales y finales. entonces x <- gsub ("^ \\ s + | \\ s + $", "", x) muchas de las funciones de lectura de R tienen esta opción: strip.white = FALSE – Jay

Respuesta

381

Probablemente la mejor manera es manejar los espacios en blanco se arrastran cuando lee tu archivo de datos Si usa read.csv o read.table, puede establecer el parámetro strip.white=TRUE.

Si desea limpiar las cuerdas después usted podría utilizar una de estas funciones:

# returns string w/o leading whitespace 
trim.leading <- function (x) sub("^\\s+", "", x) 

# returns string w/o trailing whitespace 
trim.trailing <- function (x) sub("\\s+$", "", x) 

# returns string w/o leading or trailing whitespace 
trim <- function (x) gsub("^\\s+|\\s+$", "", x) 

Para utilizar una de estas funciones en myDummy$country:

myDummy$country <- trim(myDummy$country) 

Para 'show' del espacio en blanco que puede usar:

paste(myDummy$country) 

que le mostrará las cadenas rodeadas de comillas (") que hacen que los espacios en blanco sean más fáciles de detectar.

+7

Como hadley lo señaló con esta expresión regular "^ \\ s + | \\ s + $ "identificará los espacios en blanco iniciales y finales. entonces x <- gsub ("^ \\ s + | \\ s + $", "", x) muchas de las funciones de lectura de R tienen esta opción: strip.white = FALSE – Jay

+0

@Jay: Gracias por la pista. Cambié las expresiones regulares en mi respuesta para usar el "\\ s" más corto en lugar de "[\ t]". – f3lix

+33

Vea también 'str_trim' en el paquete' stringr'. –

8

Usa grep o grepl para buscar observaciones con espacios en blanco y sub para eliminarlas.

names<-c("Ganga Din\t","Shyam Lal","Bulbul ") 
grep("[[:space:]]+$",names) 
[1] 1 3 
grepl("[[:space:]]+$",names) 
[1] TRUE FALSE TRUE 
sub("[[:space:]]+$","",names) 
[1] "Ganga Din" "Shyam Lal" "Bulbul" 
+7

O, un poco más sucinto, '"^\\ s + | \\ s + $ "' – hadley

+4

Solo quería señalar, que uno tendrá que usar 'gsub' en lugar de' sub' con la expresión regular de hadley. Con 'sub' se eliminará el espacio en blanco al final si no hay espacio en blanco delante ... – f3lix

+0

No sabía que podía usar \ s etc. con perl = FALSE. Los documentos dicen que la sintaxis POSIX se usa en ese caso, pero la sintaxis aceptada es en realidad un superconjunto definido por la biblioteca de expresiones regulares de TRE http://laurikari.net/tre/documentation/regex-syntax/ –

9

AD1) Para ver los espacios en blanco que se podría llamar directamente print.data.frame con argumentos modificados:

print(head(iris), quote=TRUE) 
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
# 1  "5.1"  "3.5"  "1.4"  "0.2" "setosa" 
# 2  "4.9"  "3.0"  "1.4"  "0.2" "setosa" 
# 3  "4.7"  "3.2"  "1.3"  "0.2" "setosa" 
# 4  "4.6"  "3.1"  "1.5"  "0.2" "setosa" 
# 5  "5.0"  "3.6"  "1.4"  "0.2" "setosa" 
# 6  "5.4"  "3.9"  "1.7"  "0.4" "setosa" 

Véase también ?print.data.frame para otras opciones.

77

Para manipular el espacio en blanco, use str_trim() en el paquete stringr. El paquete tiene un manual con fecha del 15 de febrero de 2013 y está en CRAN. La función también puede manejar vectores de cadena.

install.packages("stringr", dependencies=TRUE) 
require(stringr) 
example(str_trim) 
d4$clean2<-str_trim(d4$V2) 

(crédito va a comentarista: R. algodón)

+0

Esta solución eliminó algunos espacios en blanco mutantes que 'recortes()' no se pudo eliminar. –

+0

@RichardTelford podría dar un ejemplo? Porque eso podría considerarse un error en los recortes. – wligtenberg

21

Un simple función para quitar espacio inicial y final:

trim <- function(x) { 
    gsub("(^[[:space:]]+|[[:space:]]+$)", "", x) 
} 

Uso:

> text = " foo bar baz 3 " 
> trim(text) 
[1] "foo bar baz 3" 
5

Preferiría un anuncio d la respuesta como un comentario al usuario56 pero aún así no puede escribir como una respuesta independiente. función Extracción de ataque y de salida espacios en blanco podría lograrse a través de trim() de paquete gdata así: ejemplo

require(gdata) 
example(trim) 

Uso:

> trim(" Remove leading and trailing blanks ") 
[1] "Remove leading and trailing blanks" 
+0

trim() también funciona a través del paquete "ráster" – Nathan

434

A partir de R 3.2.0 una nueva función se introdujo para retirar líderes/espacios en blanco de cola:

trimws() 

Ver: http://stat.ethz.ch/R-manual/R-patched/library/base/html/trimws.html

+2

Depende de la definición de una mejor respuesta. Esta respuesta es buena de saber (+1) pero en una prueba rápida, no fue tan rápido como algunas de las alternativas que existen. – A5C1D2H2I1M1N2O1R2T1

+0

no parece funcionar para cadenas de varias líneas, a pesar de que '\ n' está en la clase de caracteres cubiertos. 'recortes (" SELECT \ n blah \ n FROM foo; ")' todavía contiene líneas nuevas. – Jubbles

+4

@Jubbles Ese es el comportamiento esperado. En la cadena que pasa a recortar no hay espacios en blanco iniciales o finales. Si desea eliminar los espacios en blanco iniciales y finales de cada una de las líneas de la cadena, primero tendrá que dividirla. De esta forma: recortes (strsplit ("SELECT \ n blah \ n FROM foo;", "\ n") [[1]]) – wligtenberg

4

Otro problema relacionado ocurre si tiene múltiples espacios de entradas entre medio:

> a <- " a string   with lots of starting, inter mediate and trailing whitespace  " 

Luego, puede dividir fácilmente esta cadena en "real" fichas usando una expresión regular para el argumento split:

> strsplit(a, split=" +") 
[[1]] 
[1] ""   "a"   "string"  "with"  "lots"  
[6] "of"   "starting," "inter"  "mediate" "and"  
[11] "trailing" "whitespace" 

Nota que si hay una coincidencia al comienzo de una cadena (no vacía), el primer elemento de la salida es '""', pero si hay una coincidencia al final de la cadena, el resultado es lo mismo que con el partido eliminado.

4

Otra opción es utilizar la función de stri_trim del paquete stringi que por defecto es la eliminación de espacio inicial y final:

> x <- c(" leading space","trailing space ") 
> stri_trim(x) 
[1] "leading space" "trailing space" 

Para la eliminación de solamente espacios iniciales, utilice stri_trim_left. Para solo eliminar espacios en blanco al final, use stri_trim_right. Cuando desee eliminar otros caracteres iniciales o finales, debe especificarlo con pattern =.

Consulte también ?stri_trim para obtener más información.

1

creé una función trim.strings() para recortar líder y/o espacios en blanco como:

# Arguments: x - character vector 
#   side - side(s) on which to remove whitespace 
#     default : "both" 
#     possible values: c("both", "leading", "trailing") 

trim.strings <- function(x, side = "both") { 
    if (is.na(match(side, c("both", "leading", "trailing")))) { 
     side <- "both" 
     } 
    if (side == "leading") { 
     sub("^\\s+", "", x) 
     } else { 
     if (side == "trailing") { 
      sub("\\s+$", "", x) 
    } else gsub("^\\s+|\\s+$", "", x) 
    } 
} 

Por ejemplo,

a <- c(" ABC123 456 ", " ABC123DEF   ") 

# returns string without leading and trailing whitespace 
trim.strings(a) 
# [1] "ABC123 456" "ABC123DEF" 

# returns string without leading whitespace 
trim.strings(a, side = "leading") 
# [1] "ABC123 456 "  "ABC123DEF   " 

# returns string without trailing whitespace 
trim.strings(a, side = "trailing") 
# [1] " ABC123 456" " ABC123DEF" 
0
myDummy[myDummy$country == "Austria "] <- "Austria" 

Después de esto, tendrá que forzar R no reconocer "Austria" como un nivel.Vamos a suponer que usted también tiene "EE.UU." y "España" como los niveles:

myDummy$country = factor(myDummy$country, levels=c("Austria", "USA", "Spain")) 

Un poco menos intimidante que la respuesta con más votos, pero aún así debería funcionar.

1

mejor método es trimws()

siguiente código se aplicará esta función a toda trama de datos

mydataframe < - data.frame (lapply (mydataframe, trimws), stringsAsFactors = FALSE)

Cuestiones relacionadas