web-dev-qa-db-ja.com

Rのデータフレーム全体から空白を削除する

データフレームにある空白を削除しようとしています(Rを使用)。データフレームは大きく(> 1GB)、すべてのデータエントリに空白を含む複数の列があります。

データフレーム全体から空白をすばやく削除する方法はありますか?私はこれを使用して、データの最初の10行のサブセットでこれを実行しようとしました:

gsub( " ", "", mydata) 

Rは私が解釈できなかった出力を返しましたが、これは機能していないようです。

str_replace( " ", "", mydata)

Rは47警告を返し、空白を削除しませんでした。

erase_all(mydata, " ")

Rは、「エラー:関数「erase_all」が見つかりませんでした」というエラーを返しました。

私はこの問題に取り組むために過去24時間を費やしてきたので、これに関するいくつかの助けを本当に感謝します。

ありがとう!

14

私があなたを正しく理解しているなら、データフレーム全体からすべての空白を削除したいのですが、使用しているコードは、列名のスペースを削除するのに適していると思います。

 apply(myData,2,function(x)gsub('\\s+', '',x))

これがうまくいくことを願っています。

これはマトリックスを返しますが、データフレームに変更する場合は、次のようにします。

as.data.frame(apply(myData,2,function(x)gsub('\\s+', '',x)))

2020年に編集:

lapplyおよびtrimws関数をboth=TRUEとともに使用すると、先頭と末尾のスペースを削除できますが、その内部は削除できません。OPから提供された入力データがなかったため、ダミーの例を追加して、結果。

データ:

df <- data.frame(val = c(" abc"," kl m","dfsd "),val1 = c("klm ","gdfs","123"),num=1:3,num1=2:4,stringsAsFactors = FALSE)

#situation:1(ベースRを使用)、スペースを削除する場合先頭と末尾のみでなく内部文字列値、trimws

cols_to_be_rectified <- names(df)[vapply(df, is.character, logical(1))]
df[,cols_to_be_rectified] <- lapply(df[,cols_to_be_rectified], trimws)

#シチュエーション:2(ベースRを使用)、文字列のデータフレーム内のすべての場所でスペースを削除する場合(文字列の内部と、先頭と末尾の末尾))。

これは、applyを使用して提案された最初のソリューションでした。applyを使用したソリューションは機能するように見えますが、非常に遅くなることに注意してください。データ内の先頭/末尾の空白またはすべての空白

cols_to_be_rectified <- names(df)[vapply(df, is.character, logical(1))]
df[,cols_to_be_rectified] <- lapply(df[,cols_to_be_rectified], function(x)gsub('\\s+','',x))

##状況:1(data.tableを使用して、先頭と末尾の空白のみを削除します)

library(data.table)
setDT(df)
cols_to_be_rectified <- names(df)[vapply(df, is.character, logical(1))]
df[,c(cols_to_be_rectified) := lapply(.SD, trimws), .SDcols = cols_to_be_rectified]

出力situation1から:

    val val1 num num1
1:  abc  klm   1    2
2: kl m gdfs   2    3
3: dfsd  123   3    4

##状況:2(data.tableを使用して、内部のすべての空白と先頭/末尾の空白を削除します)

cols_to_be_rectified <- names(df)[vapply(df, is.character, logical(1))]
df[,c(cols_to_be_rectified) := lapply(.SD, function(x)gsub('\\s+', '', x)), .SDcols = cols_to_be_rectified]

出力状況2から:

    val val1 num num1
1:  abc  klm   1    2
2:  klm gdfs   2    3
3: dfsd  123   3    4

両方の状況の出力の違いに注意してください。行番号2では、trimwsを使用すると、先頭と末尾の空白を削除できますが、正規表現ソリューションを使用すると、すべての空白を削除できます。

これが役に立てば幸いです、ありがとう

21
PKumar

回答の多くは古いので、2019年には、単純なdplyr回答を使用して、文字列のみを操作して末尾と先頭の空白を削除します。

_library(dplyr)
library(stringr)

data %>%
  mutate_if(is.character, str_trim)
_

空白除去の別のフレーバーが必要な場合は、str_trim()関数を他の関数に切り替えることができます。

18
Adam

FremzyとStamperからのコメントをピックアップして、これはデータの空白をクリーンアップするための私の便利なルーチンです。

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

他の人が指摘したように、これはすべてのタイプをキャラクターに変更します。私の作業では、最初に元のファイルで使用可能なタイプと必要な変換を決定します。トリミング後、必要なタイプを再適用します。

元のタイプに問題がない場合は、以下のMarkusNのソリューションを適用してください https://stackoverflow.com/a/37815274/2200542

Excelファイルを使用するユーザーは、読み取り時にデフォルトでtrim_ws = TRUEに設定されているreadxlパッケージを探索することをお勧めします。

FremzyとMielniczukを取り上げて、次の解決策を見つけました。

data.frame(lapply(df, function(x) if(class(x)=="character") trimws(x) else(x)), stringsAsFactors=F)

数値と文字の混合データフレームで機能し、文字列のみを操作します。

4
MarkusN

このような大きなデータセットを処理している場合は、data.tableの速度から本当にメリットがあります。

library(data.table)

setDT(df)

for (j in names(df)) set(df, j = j, value = df[[trimws(j)]]) 

これが最速のソリューションになると思います。このコード行はdata.tableset演算子を使用しており、列を非常に高速にループします。ここに素敵な説明があります: セットでの高速ループ

3
rafa.pereira

Rは、このようなファイルサイズに適したツールではありません。ただし、2つのオプションがあります。

Ffdplyとff baseを使用する

ffおよびffbaseパッケージを使用します。

library(ff)
library(ffabse)
x <- read.csv.ffdf(file=your_file,header=TRUE, VERBOSE=TRUE,
                 first.rows=1e4, next.rows=5e4)
x$split = as.ff(rep(seq(splits),each=nrow(x)/splits))
ffdfdply( x, x$split , BATCHBYTES=0,function(myData)        
             apply(myData,2,function(x)gsub('\\s+', '',x))

Sedを使用(私の好み)

sed -ir "s/(\S)\s+(/S)/\1\2/g;s/^\s+//;s/\s+$//" your_file 
3
agstudy

R 3.2のすべての列でtrimws関数を使用できます。

myData[,c(1)]=trimws(myData[,c(1)])

データセット内のすべての列に対してこれをループできます。大規模なデータセットでも優れたパフォーマンスを発揮します。

2
Fremzy

dplyrだけが関係する1つの可能性は次のとおりです。

data %>%
 mutate_if(is.character, trimws)

または、すべての変数がクラス文字であることを考えると:

data %>%
 mutate_all(trimws)
2
tmfmnk

data.frameで変数クラスを維持する場合は、applyを使用すると、すべての変数がmatrixまたはcharacterに変換されるnumericが出力されるため、それらを上書きすることを知っておく必要があります。 FremzyとAnthony Simon Mielniczukのコードを基にして、data.frameの列をループ処理して、クラスfactorまたはcharacterの列のみの空白を削除できます(データクラスを維持します)。

for (i in names(mydata)) {
  if(class(mydata[, i]) %in% c("factor", "character")){
    mydata[, i] <- trimws(mydata[, i])
  }
}
1
r3robertson

次のようなdfを考えると、sapplyを使用した簡単なアプローチも機能すると思います。

_dat<-data.frame(S=LETTERS[1:10],
            M=LETTERS[11:20],
            X=c(rep("A:A",3),"?","A:A ",rep("G:G",5)),
            Y=c(rep("T:T",4),"T:T ",rep("C:C",5)),
            Z=c(rep("T:T",4),"T:T ",rep("C:C",5)),
            N=c(1:3,'4 ','5 ',6:10),
            stringsAsFactors = FALSE)
_

_dat$N_によって_'4 ' & '5 '_がクラス文字になることに気づくでしょう(class(dat$N)で確認できます)

Numeic列のスペースを取り除くには、_as.numeric_または_as.integer_を使用してnumericに変換するだけです。

dat$N<-as.numeric(dat$N)

すべてのスペースを削除する場合は、次のようにします。

_dat.b<-as.data.frame(sapply(dat,trimws),stringsAsFactors = FALSE)
_

そして再び、列Nで_as.numeric_を使用します(sapplyがcharacterに変換するため)

_dat.b$N<-as.numeric(dat.b$N)
_
0