Come tagliare gli spazi bianchi iniziali e finali?


360

Sto riscontrando alcuni problemi con lo spazio bianco iniziale e finale in un data.frame. Ad esempio, mi piace dare un'occhiata a uno specifico rowin data.framebase a una determinata condizione:

> 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)

Mi chiedevo perché non avevo ottenuto l'output atteso dal momento che il paese Austria ovviamente esisteva nel mio data.frame. Dopo aver esaminato la mia cronologia del codice e aver cercato di capire cosa è andato storto, ho provato:

> 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

Tutto quello che ho cambiato nel comando è uno spazio bianco aggiuntivo dopo l'Austria.

Sorgono ovviamente ulteriori fastidiosi problemi. Ad esempio, quando mi piace unire due frame in base alla colonna del paese. Uno data.frameusa "Austria "mentre l'altro ha "Austria". La corrispondenza non funziona.

  1. C'è un bel modo di "mostrare" lo spazio bianco sul mio schermo in modo che io sia a conoscenza del problema?
  2. E posso rimuovere lo spazio bianco iniziale e finale in R?

Finora ho usato una semplice Perlsceneggiatura che rimuove lo spazio bianco, ma sarebbe bello se in qualche modo riuscissi a farlo all'interno di R.


1
Ho appena visto che sub()usa anche la Perlnotazione. Mi dispiace per quello. Proverò a usare la funzione. Ma per la mia prima domanda non ho ancora una soluzione.
mropa,

4
Come indicato da Hadley, questa regex "^ \\ s + | \\ s + $" identificherà gli spazi bianchi iniziali e finali. così x <- gsub ("^ \\ s + | \\ s + $", "", x) molte delle funzioni di lettura di R hanno questa opzione: strip.white = FALSE
Jay

Risposte:


456

Probabilmente il modo migliore è gestire gli spazi bianchi finali quando leggi il tuo file di dati. Se si utilizza read.csvo read.tableè possibile impostare il parametro strip.white=TRUE.

Se si desidera pulire le stringhe in seguito, è possibile utilizzare una di queste funzioni:

# 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)

Per utilizzare una di queste funzioni su myDummy$country:

 myDummy$country <- trim(myDummy$country)

Per "mostrare" lo spazio bianco che puoi usare:

 paste(myDummy$country)

che ti mostrerà le stringhe racchiuse tra virgolette (") rendendo più facile individuare gli spazi bianchi.


7
Come indicato da Hadley, questa regex "^ \\ s + | \\ s + $" identificherà gli spazi bianchi iniziali e finali. così x <- gsub ("^ \\ s + | \\ s + $", "", x) molte delle funzioni di lettura di R hanno questa opzione: strip.white = FALSE
Jay

50
Vedi anche str_trimnel stringrpacchetto.
Richie Cotton,

1
Più uno per "Funzione Trim ora memorizzata per uso futuro" - grazie!
Chris Beeley,

4
Sfortunatamente, strip.white = TRUE funziona solo su stringhe non quotate.
Rodrigo,

2
C'è un modo molto più semplice per tagliare gli spazi bianchi in R 3.2.0. Vedi la prossima risposta!
Alex,

519

A partire da R 3.2.0 è stata introdotta una nuova funzione per rimuovere gli spazi bianchi iniziali / finali:

trimws()

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


2
Dipende dalla definizione di una migliore risposta. Questa risposta è buona da sapere di (+1) ma in un test veloce, non è stato veloce come alcune delle alternative là fuori.
A5C1D2H2I1M1N2O1R2T1

non sembra funzionare con stringhe multilinea, nonostante \nsia nella classe di caratteri coperta. trimws("SELECT\n blah\n FROM foo;")contiene ancora nuove righe.
Jubbles

6
@Jubbles Questo è il comportamento previsto. Nella stringa che passi ai trimw non ci sono spazi bianchi iniziali o finali. Se vuoi rimuovere spazi bianchi iniziali e finali da ciascuna delle linee nella stringa, dovrai prima dividerlo. In questo modo: trimws (strsplit ("SELECT \ n blah \ n FROM foo;", "\ n") [[1]])
wligtenberg,

1
Sebbene sia una funzione integrata per le versioni recenti di R, fa 'solo' una regex in stile PERL sotto il cofano. Mi sarei aspettato un codice C personalizzato veloce per fare questo. Forse il trimwsregex è abbastanza veloce. stringr::str_trim(basato su stringi) è anche interessante in quanto utilizza una libreria di stringhe internazionalizzata completamente indipendente. Penseresti che lo spazio bianco sarebbe immune da problemi con l'internazionalizzazione, ma mi chiedo. Non ho mai visto un confronto tra i risultati di vs stringr/ stringio nativi di riferimento.
Jack Wasey,

Per qualche motivo non sono riuscito a capire, trimws()non ho rimosso i miei spazi bianchi principali, mentre Bryan è trim.strings()al di sotto (solo 1 voto, il mio!)
Ha

89

Per manipolare lo spazio bianco, utilizzare str_trim () nel pacchetto stringr. Il pacchetto ha un manuale datato 15.2013 febbraio ed è in CRAN. La funzione può anche gestire vettori di stringhe.

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

(il merito va al commentatore: R. Cotton)


2
Questa soluzione ha rimosso alcuni spazi bianchi mutanti che trimws()non è stato in grado di rimuovere.
Richard Telford,

1
@RichardTelford potresti fornire un esempio? Perché potrebbe essere considerato un bug nei trimws.
wligtenberg,

IMO questa è la soluzione migliore. Non molto di codice e altamente performante
Peter,

Grazie per la richiesta (stringr) la loro documentazione o esempi non avevano questa riga di codice richiesta!
pgee70,

23

Una semplice funzione per rimuovere gli spazi iniziali e finali:

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

Uso:

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

11

ad1) Per vedere gli spazi bianchi puoi chiamare direttamente print.data.framecon argomenti modificati:

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"

Vedi anche ?print.data.frameper altre opzioni.


9

Usa grep o grepl per trovare osservazioni con spazi bianchi e sottotitoli per sbarazzartene.

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 po 'più succintamente,"^\\s+|\\s+$"
Hadley,

4
Volevo solo far notare che si dovrà usare gsubinvece che subcon la regexp di Hadley. Con subesso
rimuoverà gli

Non sapevo che potresti usare \ s ecc. Con perl = FALSE. I documenti dicono che la sintassi POSIX viene utilizzata in quel caso, ma la sintassi accettata è in realtà un superset definito dalla libreria di regex TRE laurikari.net/tre/documentation/regex-syntax
Jyotirmoy Bhattacharya

5

Preferirei aggiungere la risposta come commento all'utente56 ma non riesco ancora a scrivere come risposta indipendente. La rimozione di spazi vuoti iniziali e finali potrebbe essere ottenuta anche tramite la funzione trim () dal pacchetto gdata:

require(gdata)
example(trim)

Esempio di utilizzo:

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

5

Un altro problema correlato si verifica se si hanno più spazi tra gli input:

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

Puoi quindi facilmente dividere questa stringa in token "reali" usando un'espressione regolare splitall'argomento:

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

Nota che se c'è una corrispondenza all'inizio di una stringa (non vuota), il primo elemento dell'output è '""', ma se c'è una corrispondenza alla fine della stringa, l'output è lo stesso di con la partita rimossa.


5

Un'altra opzione è quella di utilizzare la stri_trimfunzione dal stringipacchetto che per impostazione predefinita rimuove gli spazi bianchi iniziali e finali:

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

Per rimuovere solo gli spazi bianchi iniziali, utilizzare stri_trim_left. Per rimuovere solo gli spazi bianchi finali, utilizzare stri_trim_right. Quando si desidera rimuovere altri caratteri iniziali o finali, è necessario specificarlo con pattern =.

Vedi anche ?stri_trimper maggiori informazioni.


2

Ho creato una trim.strings ()funzione per tagliare gli spazi bianchi iniziali e / o finali come:

# 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)
    } 
} 

Per illustrazione,

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"   

1

Il metodo migliore è trimws ()

Il codice seguente applicherà questa funzione all'intero frame di dati

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


o df[] <- lapply(df, trimws)per essere più compatto. Ma in entrambi i casi costringerà le colonne al personaggio. df[sapply(df,is.character)] <- lapply(df[sapply(df,is.character)], trimws)per essere al sicuro.
Moody_Mudskipper,

1

Ho provato a tagliare (). Funziona bene con spazi bianchi e '\ n'. x = '\ n Harden, J. \ n'

trim (x)


0
myDummy[myDummy$country == "Austria "] <- "Austria"

Successivamente, dovrai forzare R a non riconoscere "Austria" come livello. Facciamo finta di avere anche "USA" e "Spagna" come livelli:

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

Un po 'meno intimidatorio della risposta più votata, ma dovrebbe comunque funzionare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.