データフレームにある空白を削除しようとしています(Rを使用)。データフレームは大きく(> 1GB)、すべてのデータエントリに空白を含む複数の列があります。
データフレーム全体から空白をすばやく削除する方法はありますか?私はこれを使用して、データの最初の10行のサブセットでこれを実行しようとしました:
gsub( " ", "", mydata)
Rは私が解釈できなかった出力を返しましたが、これは機能していないようです。
str_replace( " ", "", mydata)
Rは47警告を返し、空白を削除しませんでした。
erase_all(mydata, " ")
Rは、「エラー:関数「erase_all」が見つかりませんでした」というエラーを返しました。
私はこの問題に取り組むために過去24時間を費やしてきたので、これに関するいくつかの助けを本当に感謝します。
ありがとう!
私があなたを正しく理解しているなら、データフレーム全体からすべての空白を削除したいのですが、使用しているコードは、列名のスペースを削除するのに適していると思います。
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
を使用すると、先頭と末尾の空白を削除できますが、正規表現ソリューションを使用すると、すべての空白を削除できます。
これが役に立てば幸いです、ありがとう
回答の多くは古いので、2019年には、単純なdplyr
回答を使用して、文字列のみを操作して末尾と先頭の空白を削除します。
_library(dplyr)
library(stringr)
data %>%
mutate_if(is.character, str_trim)
_
空白除去の別のフレーバーが必要な場合は、str_trim()
関数を他の関数に切り替えることができます。
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)
数値と文字の混合データフレームで機能し、文字列のみを操作します。
このような大きなデータセットを処理している場合は、data.table
の速度から本当にメリットがあります。
library(data.table)
setDT(df)
for (j in names(df)) set(df, j = j, value = df[[trimws(j)]])
これが最速のソリューションになると思います。このコード行はdata.table
のset
演算子を使用しており、列を非常に高速にループします。ここに素敵な説明があります: セットでの高速ループ 。
Rは、このようなファイルサイズに適したツールではありません。ただし、2つのオプションがあります。
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 -ir "s/(\S)\s+(/S)/\1\2/g;s/^\s+//;s/\s+$//" your_file
R 3.2のすべての列でtrimws関数を使用できます。
myData[,c(1)]=trimws(myData[,c(1)])
データセット内のすべての列に対してこれをループできます。大規模なデータセットでも優れたパフォーマンスを発揮します。
dplyr
だけが関係する1つの可能性は次のとおりです。
data %>%
mutate_if(is.character, trimws)
または、すべての変数がクラス文字であることを考えると:
data %>%
mutate_all(trimws)
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])
}
}
次のような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)
_