![](/img/trans.png)
[英]Removing rows based on a stretch of repeated values in R, but not the whole data frame
[英]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
lapply
和trimws
函数可以删除前导和尾随空格,但不能删除其中。由于 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 个选项:
使用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)])
您可以为数据集中的所有列循环此操作。 它在大型数据集上也具有良好的性能。
如果您正在处理这样的大型数据集,您真的可以从data.table
的速度中data.table
。
library(data.table)
setDT(df)
for (j in names(df)) set(df, j = j, value = df[[trimws(j)]])
我希望这是最快的解决方案。 这行代码使用了data.table
的set
运算符,它非常快速地遍历列。 这里有一个很好的解释: Fast looping with set 。
如果您想维护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])
}
}
我认为 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.numeric
或as.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.