簡體   English   中英

從 R 中的整個數據幀中刪除空白

[英]Removing Whitespace From a Whole Data Frame in R

我一直在嘗試刪除數據框中的空白區域(使用 R) 數據框很大 (>1gb) 並且有多個列,每個數據條目中都包含空格。

有沒有一種快速的方法可以從整個數據框中刪除空白? 我一直在嘗試使用以下方法對前 10 行數據的子集執行此操作:

gsub( " ", "", mydata) 

這似乎不起作用,盡管 R 返回了我無法解釋的輸出。

str_replace( " ", "", mydata)

R 返回了47 個警告並且沒有刪除空格。

erase_all(mydata, " ")

R 返回一個錯誤,指出“錯誤:找不到函數“erase_all””

我真的很感激這方面的一些幫助,因為我花了過去 24 小時試圖解決這個問題。

謝謝!

很多答案都是舊的,所以在 2019 年這里是一個簡單的dplyr解決方案,它將只對字符列進行操作以刪除尾隨和前導空格。

library(dplyr)
library(stringr)

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

## ===== 2020 edit for dplyr (>= 1.0.0) =====
df %>% 
  mutate(across(where(is.character), str_trim))

如果您想要不同風格的空白刪除,您可以將str_trim()函數切換為其他函數。

# for example, remove all spaces
df %>% 
  mutate(across(where(is.character), str_remove_all, pattern = fixed(" ")))

如果我理解正確,那么您想從整個數據框中刪除所有空格,我猜您正在使用的代碼適用於刪除列名中的空格。我認為您應該嘗試以下操作:

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

希望這有效。

但是,這將返回一個矩陣,如果要將其更改為數據框,請執行以下操作:

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

2020年編輯:

使用帶有both=TRUE lapplytrimws函數可以刪除前導和尾隨空格,但不能刪除其中。由於 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 (Using Base 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 (Using Base R) ,當我們想要刪除字符列中數據幀中每個位置的空格(字符串內部以及首尾兩端)。

這是使用 apply 提出的初始解決方案,請注意使用 apply 的解決方案似乎有效但會很慢,而且問題顯然不是很清楚,如果 OP 真的想刪除前導/尾隨空白或每個空白數據

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]

情況 1 的輸出

 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我們可以刪除前導和尾隨空白,但使用正則表達式解決方案我們能夠刪除每個空白。

我希望這會有所幫助,謝謝

根據 Fremzy 和 Stamper 的評論,這現在是我清理數據中空白的方便例程:

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

正如其他人所指出的那樣,這會將所有類型更改為字符。 在我的工作中,我首先確定原始文件中可用的類型和所需的轉換。 修剪后,我重新應用所需的類型。

如果您的原始類型沒問題,請在https://stackoverflow.com/a/37815274/2200542下面應用 MarkusN 的解決方案

那些使用 Excel 文件的人可能希望探索 readxl 包,它在閱讀時默認為 trim_ws = TRUE。

拿起 Fremzy 和 Mielniczuk,我得出了以下解決方案:

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

它適用於混合數字/字符數據框,僅操作字符列。

僅涉及dplyr一種可能性可能是:

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

或者考慮到所有變量都是類字符:

data %>%
 mutate_all(trimws)

R 根本不是適合這種文件大小的工具。 但是有 2 個選項:

使用 ffdply 和 ff 基礎

使用ffffbase包:

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 

您可以在 R 3.2 中的所有列上使用 trimws 函數。

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

您可以為數據集中的所有列循環此操作。 它在大型數據集上也具有良好的性能。

如果您正在處理這樣的大型數據集,您真的可以從data.table的速度中data.table

library(data.table)

setDT(df)

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

我希望這是最快的解決方案。 這行代碼使用了data.tableset運算符,它非常快速地遍歷列。 這里有一個很好的解釋: Fast looping with set

如果您想維護data.frame的變量類 - 您應該知道使用apply會破壞它們,因為它輸出一個matrix ,其中所有變量都轉換為characternumeric 基於 Fremzy 和 Anthony Simon Mielniczuk 的代碼,您可以遍歷 data.frame 的列並僅從類factorcharacter列中修剪空白(並維護您的數據類):

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

我認為 sapply 的簡單方法也有效,給定 df 如下:

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)

要擺脫numeric列上的空格,只需使用as.numericas.integer轉換為numeric as.integer

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

如果要刪除所有空格,請執行以下操作:

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

再次在 col N 上使用as.numeric (ause sapply 會將其轉換為character

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM