Önde gelen ve arkadaki boşluklar nasıl kesilir?


360

Bir data.frame içinde önde gelen ve sondaki boşluk ile bazı sorunlar yaşıyorum. Örneğin ben Belli bir bölüme bakmak ister rowbir de data.framebelli bir koşula dayalı:

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

Avusturya ülkemde açıkça var olduğu için neden beklenen çıktıyı alamadığımı merak ediyordum data.frame. Kod geçmişime bakıp neyin yanlış gittiğini anlamaya çalıştıktan sonra denedim:

> 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

Komutada değiştirdiğim tek şey Avusturya'dan sonra ek bir boşluk.

Daha fazla can sıkıcı problemler ortaya çıkıyor. Örneğin, ülke sütununa göre iki kareyi birleştirmek istediğimde. Biri diğer çerçeveyi data.framekullanırken kullanır . Eşleme çalışmıyor."Austria ""Austria"

  1. Sorunun farkına varabilmem için boşlukları ekranımda 'göstermenin' güzel bir yolu var mı?
  2. Ve R'deki önde gelen ve sondaki boşlukları kaldırabilir miyim?

Şimdiye kadar Perlboşlukları kaldıran basit bir senaryo yazıyordum ama bir şekilde R içinde yapabilirsem iyi olurdu.


1
Az önce gösterimi de sub()kullandığını gördüm Perl. Bunun için üzgünüm. Ben bu işlevi kullanmaya çalışacağım. Ama ilk sorum için henüz bir çözümüm yok.
mropa

4
Hadley'in işaret ettiği gibi bu regex "^ \\ s + | \\ s + $" önde gelen ve sondaki boşlukları tanımlayacaktır. yani x <- gsub ("^ \\ s + | \\ s + $", "", x) R'nin okuma işlevlerinin çoğu şu seçeneğe sahiptir: strip.white = YANLIŞ
Jay 15

Yanıtlar:


458

Muhtemelen en iyi yol, veri dosyanızı okurken arka boşlukları işlemektir. Kullanırsanız read.csvveya read.tableparametreyi ayarlayabilirsiniz strip.white=TRUE.

Daha sonra dizeleri temizlemek isterseniz, aşağıdaki işlevlerden birini kullanabilirsiniz:

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

Bu işlevlerden birini üzerinde kullanmak için myDummy$country:

 myDummy$country <- trim(myDummy$country)

Kullanabileceğiniz boşluğu 'göstermek' için:

 paste(myDummy$country)

böylece tırnak işaretleriyle (") çevrelenen dizeler, beyaz boşlukların daha kolay fark edilmesini sağlar.


7
Hadley'in işaret ettiği gibi bu regex "^ \\ s + | \\ s + $" önde gelen ve sondaki boşlukları tanımlayacaktır. yani x <- gsub ("^ \\ s + | \\ s + $", "", x) R'nin okuma işlevlerinin birçoğu şu seçeneğe sahiptir: strip.white = YANLIŞ
Jay

50
Ayrıca bakınız str_trimde stringrpaketin.
Richie Cotton

1
Artı "şimdi gelecekte kullanım için saklanan Trim fonksiyonu" - teşekkürler!
Chris Beeley

4
Ne yazık ki, strip.white = TRUE yalnızca tırnak içine alınmayan dizelerde çalışır.
Rodrigo

2
R 3.2.0'da boşluk düzeltmenin çok daha kolay bir yolu var. Bir sonraki cevaba bakınız!
Alex

519

R 3.2.0'dan itibaren önde gelen / arkadaki boşlukları kaldırmak için yeni bir fonksiyon getirildi:

trimws()

Bkz. Http://stat.ethz.ch/R-manual/R-patched/library/base/html/trimws.html


2
En iyi cevabın tanımına bağlıdır. Bu cevap (+1) bilmek güzel ama hızlı bir test, orada bazı alternatifler kadar hızlı değildi.
A5C1D2H2I1M1N2O1R2T1

\nkapsanan karakter sınıfında olmasına rağmen çok satırlı dizelerde işe yaramıyor gibi görünüyor . trimws("SELECT\n blah\n FROM foo;")hala yeni satır içeriyor.
Aralık'ta Jubbles

6
@Jubbles Beklenen davranış budur. Dize içinde kırpıntılara geçtiğinizde önde veya arkada boşluk yoktur. Dizedeki satırların her birinden önde gelen ve arkadaki beyaz boşlukları kaldırmak istiyorsanız, önce bölmeniz gerekir. Bunun gibi: trimws (strsplit ("SELECT \ n blah \ n FROM foo;", "\ n") [[1]])
wligtenberg

1
R'nin son sürümleri için yerleşik bir işlev olmasına rağmen, kaputun altında bir PERL stili normal ifade yapıyor. Bunu yapmak için bazı hızlı özel C kodu beklemiş olabilirim. Belki trimwsnormal ifade yeterince hızlıdır. stringr::str_trim(esas olarak stringi), tamamen bağımsız bir uluslararası dizgi kütüphanesi kullanmasıyla da ilginçtir. Beyaz alanın uluslararasılaşma ile ilgili sorunlardan muaf olacağını düşünürdünüz, ama merak ediyorum. Hiç yerli vs stringr/ stringiveya herhangi bir kıyaslama sonuçları karşılaştırması görmedim .
Jack Wasey

Bir nedenden ötürü anlayamadım, trimws()önde gelen beyaz alanlarımı kaldırmadım, Bryan ise trim.strings()aşağıda (sadece 1 oy, benim!) Yaptı ...
PatrickT

89

Beyaz alanı değiştirmek için stringr paketinde str_trim () kullanın. Paket 15 Şubat 2013 tarihli el kitabına sahiptir ve CRAN'dadır. İşlev, dize vektörlerini de işleyebilir.

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

(kredi yorumcuna gider: R. Cotton)


2
Bu çözüm, kaldırılamayan bazı mutant boşlukları trimws()kaldırdı.
Richard Telford

1
@RichardTelford bir örnek verebilir misiniz? Çünkü bu trimlerdeki bir hata olarak düşünülebilir.
wligtenberg

IMO bu en iyi çözümdür. Çok fazla kod ve yüksek performans
Peter

Requir (stringr) için teşekkür ederiz, belgeleri veya örnekleri bu gerekli kod satırına sahip değildi!
pgee70

23

Öndeki ve sondaki boşlukları kaldırmak için basit bir işlev :

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

Kullanımı:

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

11

ad1) Beyaz boşlukları görmek için print.data.frame, değiştirilmiş bağımsız değişkenlerle doğrudan arayabilirsiniz :

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"

?print.data.frameDiğer seçenekler için de bakınız .


9

Boşluklarla ve altlardan kurtulmak için gözlemleri bulmak için grep veya grepl kullanın.

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
Veya, biraz daha özlü bir şekilde,"^\\s+|\\s+$"
hadley

4
Sadece belirtmek istedim , hadley regexp gsubyerine kullanmak subzorunda kalacak. Bununla subbirlikte iz
süren

Perl = FALSE ile \ s vb. Kullanabileceğinizi bilmiyordum. Dokümanlar bu durumda POSIX sözdiziminin kullanıldığını söylüyor, ancak kabul edilen sözdizimi aslında TRE regex kütüphanesi tarafından tanımlanan bir üst küme laurikari.net/tre/documentation/regex-syntax
Jyotirmoy Bhattacharya 14:10

5

Cevabı user56'ya yorum olarak eklemeyi tercih ediyorum, ancak bağımsız bir cevap olarak yazamıyorum. Ön ve arka boşlukları kaldırmak, gdata paketinden trim () işlevi ile de elde edilebilir:

require(gdata)
example(trim)

Kullanım örneği:

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

5

Girdiler arasında birden çok boşluk varsa, ilgili başka bir sorun oluşur:

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

Daha sonra, splitargümana normal bir ifade kullanarak bu dizeyi kolayca "gerçek" jetonlara bölebilirsiniz :

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

(Boş olmayan) bir dizenin başında eşleşme varsa, çıktının ilk öğesinin "" "olduğunu, ancak dizenin sonunda bir eşleşme varsa çıktının aynı olduğunu unutmayın. maç kaldırıldı.


5

Başka bir seçenek de, önde gelen ve sondaki boşlukları kaldırmaya varsayılan olarak paketten gelen stri_trimişlevi kullanmaktır stringi:

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

Yalnızca önde gelen boşlukları kaldırmak için kullanın stri_trim_left. Yalnızca arka boşlukları kaldırmak için kullanın stri_trim_right. Diğer önde gelen veya sondaki karakterleri kaldırmak istediğinizde, ile belirtmeniz gerekir pattern =.

Daha ?stri_trimfazla bilgi için ayrıca bakınız .


2

Ben trim.strings ()önde gelen ve / veya sondaki boşluk kırpmak için bir fonksiyon yarattı :

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

Gösterim amacıyla,

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

En iyi yöntem trimws ()

Aşağıdaki kod bu işlevi tüm veri çerçevesine uygulayacaktır

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


ya df[] <- lapply(df, trimws)da daha kompakt olmak. Ancak her iki durumda da sütunları karaktere zorlar. df[sapply(df,is.character)] <- lapply(df[sapply(df,is.character)], trimws)güvende olmak.
Moody_Mudskipper

1

Ben trim () denedim. Beyaz boşlukların yanı sıra '\ n' ile de iyi çalışır. x = '\ n Harden, J. \ n'

Döşeme (x)


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

Bundan sonra, R'yi "Avusturya" yı bir seviye olarak tanımamaya zorlamanız gerekir. Seviye olarak "ABD" ve "İspanya" da olduğunu varsayalım:

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

Oylanan en yüksek tepkiden biraz daha az korkutucu ama yine de işe yaramalı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.