先頭と末尾の空白を削除する方法は?


360

data.frameの先頭と末尾の空白に問題があります。例えば私の特定を見てみたいとrowしてdata.frame、特定の条件に基づいて:

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

オーストリアが明らかに私の国に存在していたので、なぜ期待した出力が得られなかったのかと思いましたdata.frame。私のコード履歴を調べ、何がうまくいかなかったかを理解しようとした後、私は試しました:

> 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

コマンドで変更したのは、オーストリアに続く追加の空白です。

さらに厄介な問題が明らかに発生します。たとえば、country列に基づいて2つのフレームをマージする場合などです。1つdata.frame"Austria "他のフレームにある間使用します"Austria"。マッチングが機能しません。

  1. 問題を認識できるように画面の空白を「表示」する良い方法はありますか?
  2. Rの先頭と末尾の空白を削除できますか?

これまでPerlは、空白を削除する単純なスクリプトを記述してきましたが、R内でなんとかできればいいのですが。


1
私もそれが記法をsub()使っているのを見ましたPerl。申し訳ありません。関数を使ってみます。しかし、最初の質問については、まだ解決策がありません。
mropa

4
ハドリーが指摘したように、この正規表現「^ \\ s + | \\ s + $」は先頭と末尾の空白を識別します。したがって、x <-gsub( "^ \\ s + | \\ s + $"、 ""、x)多くのRの読み取り関数には、このオプションがあります:strip.white = FALSE
Jay

回答:


456

おそらく最良の方法は、データファイルを読み取るときに末尾の空白を処理することです。を使用するread.csvread.table、パラメータを設定できますstrip.white=TRUE

後で文字列を消去したい場合は、次のいずれかの関数を使用できます。

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

これらの関数の1つをで使用するにはmyDummy$country

 myDummy$country <- trim(myDummy$country)

使用できる空白を「表示」するには:

 paste(myDummy$country)

引用符( ")で囲まれた文字列が表示され、空白を見つけやすくなります。


7
ハドリーが指摘したように、この正規表現「^ \\ s + | \\ s + $」は先頭と末尾の空白を識別します。したがって、x <-gsub( "^ \\ s + | \\ s + $"、 ""、x)多くのRの読み取り関数には、このオプションがあります:strip.white = FALSE
Jay

50
参照してくださいstr_trimstringrパッケージ。
リッチーコットン

1
さらに、「Trim機能が将来の使用のために保存されました」の1つ-ありがとうございます!
Chris Beeley、2012年

4
残念ながら、strip.white = TRUEは、引用符で囲まれていない文字列に対してのみ機能します。
ロドリゴ

2
R 3.2.0では、空白を削除する簡単な方法があります。次の答えを見てください!
Alex

519

R 3.2.0以降、先頭/末尾の空白を削除するための新しい関数が導入されました。

trimws()

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


2
ベストアンサーの定義によって異なります。この答えは(+1)について知っておくと便利ですが、簡単なテストでは、他の選択肢のいくつかほど速くはありませんでした。
A5C1D2H2I1M1N2O1R2T1 2015年

\n対象の文字クラスに属しているにもかかわらず、複数行の文字列では機能しないようです。trimws("SELECT\n blah\n FROM foo;")まだ改行が含まれています。
Jubbles

6
@Jubblesこれは予想される動作です。trimwsに渡す文字列には、先頭または末尾の空白はありません。文字列の各行から先頭と末尾の空白を削除する場合は、最初にそれを分割する必要があります。このように:trimws(strsplit( "SELECT \ n blah \ n FROM foo;"、 "\ n")[[1]])
wligtenberg

1
Rの最近のバージョンの組み込み関数ですが、内部でPERLスタイルの正規表現を実行するだけです。これを行うには、高速のカスタムCコードを期待していました。多分trimws正規表現は十分に速いです。stringr::str_trim(に基づくstringi)は、完全に独立した国際化された文字列ライブラリを使用するという点でも興味深いです。空白は国際化の問題の影響を受けないと思いますが、私は疑問に思います。ネイティブvs stringr/ stringiまたはその他のベンチマークの結果の比較を見たことがありません。
Jack Wasey

何らかの理由で、私は理解できずtrimws()、私の先頭の空白を削除しませんでしたが、trim.strings()下のブライアン(たった1票、私のもの)は
削除

89

空白を操作するには、ストリンガーパッケージのstr_trim()を使用します。パッケージには2013年2月15日付けのマニュアルがあり、CRANにあります。この関数は文字列ベクトルも処理できます。

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

(クレジットはコメンターに送られます:R.コットン)


2
このソリューションtrimws()は、削除できなかった一部のミュータント空白を削除しました。
Richard Telford

1
@RichardTelfordに例を提供できますか?それはトリムのバグと考えられるからです。
wligtenberg 2017

IMOこれは最良のソリューションです。コードはそれほど多くなく、パフォーマンスも高い
Peter

require(stringr)のおかげで、ドキュメントや例にこの必要なコード行がありませんでした!
pgee70

23

先頭と末尾の空白を削除する単純な関数

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

使用法:

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

11

ad1)空白を表示するにはprint.data.frame、変更した引数を使用して直接呼び出すことができます。

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.frame他のオプションについても参照してください。


9

grepまたはgreplを使用して空白を含む観測を検索し、subを削除して空白を削除します。

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
それとも、もう少し簡潔に、"^\\s+|\\s+$"
ハドレー

4
指摘したいのgsubsub、ハドリーの正規表現の代わりに使用する必要があるということです。ではsub、それは...何も先頭の空白が存在しない場合にのみ、末尾の空白を削除します
f3lix

\ sなどをperl = FALSEで使用できることを知りませんでした。そのドキュメントではPOSIX構文が使用されていると述べていますが、受け入れられた構文は実際にはTRE正規表現ライブラリlaurikari.net/tre/documentation/regex-syntax
Jyotirmoy Bhattacharya

5

回答をコメントとしてuser56に追加したいのですが、それでも独立した回答として書くことはできません。先頭と末尾の空白の削除は、gdataパッケージからtrim()関数を使用して行うこともできます。

require(gdata)
example(trim)

使用例:

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

5

入力の間に複数のスペースがある場合、別の関連する問題が発生します。

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

次に、split引数に正規表現を使用して、この文字列を「実際の」トークンに簡単に分割できます。

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

(空ではない)文字列の先頭に一致がある場合、出力の最初の要素は '""'ですが、文字列の末尾に一致がある場合、出力は次のようになります。マッチを削除しました。


5

別のオプションはstri_trimstringiパッケージの関数を使用して、デフォルトで先頭と末尾の空白を削除することです。

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

先頭の空白のみを削除するには、を使用しますstri_trim_left。末尾の空白のみを削除するには、を使用しますstri_trim_right。他の先頭または末尾の文字を削除する場合は、それをで指定する必要がありpattern =ます。

詳細については?stri_trim、こちらもご覧ください。


2

trim.strings ()先頭と末尾の空白を削除する関数を次のように作成しました。

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

説明のために、

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

最良の方法はtrimws()です

次のコードは、この関数をデータフレーム全体に適用します

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


またはdf[] <- lapply(df, trimws)よりコンパクトになります。ただし、どちらの場合も列を文字に強制変換します。df[sapply(df,is.character)] <- lapply(df[sapply(df,is.character)], trimws)安全であるために。
Moody_Mudskipper

1

私はtrim()を試しました。空白と '\ n'でうまく機能します。x = '\ n Harden、J. \ n'

トリム(x)


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

この後、Rに「オーストリア」をレベルとして認識させないようにする必要があります。レベルとして「USA」と「Spain」も持っているとしましょう。

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

最高投票数の回答よりも少し威圧的ではありませんが、それでも機能するはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.