我如何修剪开头和结尾空白?

我有一些麻烦的前导和尾随空白在一个数据。框架。

例如,我根据特定条件查看data.frame中的特定row:

> 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

我所更改的命令只是在奥地利之后增加了一个空白。

显然还会出现更多烦人的问题。例如,当我喜欢根据国家列合并两帧时。一个data.frame使用"Austria ",而另一个帧使用"Austria"。匹配不起作用。

  1. 有没有一种很好的方法来“显示”屏幕上的空白,让我意识到这个问题?
  2. 我能移除R开头和结尾的空白吗?

到目前为止,我曾经写过一个简单的Perl脚本,它删除了白色的步伐,但如果我能以某种方式在R中做它就好了。

359070 次浏览

最好的方法可能是在读取数据文件时处理后面的空白。如果你使用read.csvread.table,你可以设置参数__abc2。

如果你想清理字符串之后,你可以使用这些函数之一:

# Returns string without leading white space
trim.leading <- function (x)  sub("^\\s+", "", x)


# Returns string without trailing white space
trim.trailing <- function (x) sub("\\s+$", "", x)


# Returns string without leading or trailing white space
trim <- function (x) gsub("^\\s+|\\s+$", "", x)

myDummy$country上使用下列函数之一:

 myDummy$country <- trim(myDummy$country)

要“显示”你可以使用的空白:

 paste(myDummy$country)

它将向您显示由引号(")包围的字符串,使空白更容易发现。

使用grepgrepl查找带有空格的观测值,使用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"

为了看到空格,你可以直接调用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

要操作空格,使用stringr包中的str_trim()。 该包的手册日期为2013年2月15日,位于凹口中。 该函数也可以处理字符串向量
install.packages("stringr", dependencies=TRUE)
require(stringr)
example(str_trim)
d4$clean2<-str_trim(d4$V2)

(图片来源:R. Cotton)

一个简单的函数来删除开头和结尾的空白:

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

用法:

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

也可以通过gdata包中的trim()函数来移除前导和后面的空格:

require(gdata)
example(trim)

使用的例子:

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

我更喜欢把答案作为评论添加到user56的,但我还不能作为一个独立的答案写作。

从R 3.2.0开始,引入了一个新的函数来移除前导/尾随空白:

trimws()

看:删除前导/后引空格 .

如果输入之间有多个空格,则会出现另一个相关问题:

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

然后,您可以轻松地将此字符串拆分为“;real"使用正则表达式赋给split参数的标记:

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

请注意,如果在(非空)字符串的开头有匹配项,输出的第一个元素是' "" ',但如果在字符串的末尾有匹配项,输出与删除匹配项后的输出相同。

另一个选项是使用stringi包中的stri_trim函数,该函数默认删除前导和尾随空格:

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

如果只移除前导空格,请使用stri_trim_left。如果只移除尾随空格,请使用stri_trim_right。当你想删除其他前导字符或尾随字符时,你必须用pattern =指定。

更多信息请参见?stri_trim

我创建了一个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"
myDummy[myDummy$country == "Austria "] <- "Austria"

在此之后,您将需要强制R不将"Austria "识别为级别。让我们假设你也有"USA""Spain"作为级别:

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

这比得票最高的回答要少一些威慑力,但它仍然有效。

最好的方法是trimws ()

下面的代码将这个函数应用到整个数据框架。

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

我试过trim()。它适用于空格和“\n”。

x = '\n              Harden, J.\n              '


trim(x)

本线程中主要方法的基准测试。这并没有捕捉到所有奇怪的情况,但到目前为止,我们仍然缺少str_trim删除空白而trimws不删除空白的例子(请看Richard Telford对这个答案的评论)。似乎并不重要- gsub选项似乎是最快的:)

x <- c(" lead", "trail ", " both ", " both and middle ", " _special")
## gsub function from https://stackoverflow.com/a/2261149/7941188
## this is NOT the function from user Bernhard Kausler, which uses
## a much less concise regex
gsub_trim <- function (x) gsub("^\\s+|\\s+$", "", x)


res <- microbenchmark::microbenchmark(
gsub = gsub_trim(x),
## https://stackoverflow.com/a/30210713/7941188
trimws = trimws(x),
## https://stackoverflow.com/a/15007398/7941188
str_trim = stringr::str_trim(x),
times = 10^5
)
res
#> Unit: microseconds
#>      expr    min     lq      mean median       uq       max neval cld
#>      gsub 20.201 22.788  31.43943 24.654  28.4115  5303.741 1e+05 a
#>    trimws 38.204 41.980  61.92218 44.420  51.1810 40363.860 1e+05  b
#>  str_trim 88.672 92.347 116.59186 94.542 105.2800 13618.673 1e+05   c
ggplot2::autoplot(res)

< img src = " https://i.imgur.com/vqKlsms.png " alt = " / >

sessionInfo()
#> R version 4.0.3 (2020-10-10)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Big Sur 10.16
#>
#> locale:
#> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
#>
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base
#>
#> loaded via a namespace (and not attached):
#>  stringr_1.4.0


使用dplyr/tidyverse mutate_allstr_trim来修剪整个数据帧:

myDummy %>%
mutate_all(str_trim)
library(tidyverse)
set.seed(335)
df <- mtcars %>%
rownames_to_column("car") %>%
mutate(car = ifelse(runif(nrow(mtcars)) > 0.4, car, paste0(car, " "))) %>%
select(car, mpg)


print(head(df), quote = T)
#>                    car    mpg
#> 1         "Mazda RX4 " "21.0"
#> 2      "Mazda RX4 Wag" "21.0"
#> 3        "Datsun 710 " "22.8"
#> 4    "Hornet 4 Drive " "21.4"
#> 5 "Hornet Sportabout " "18.7"
#> 6           "Valiant " "18.1"


df_trim <- df %>%
mutate_all(str_trim)


print(head(df_trim), quote = T)
#>                   car    mpg
#> 1         "Mazda RX4"   "21"
#> 2     "Mazda RX4 Wag"   "21"
#> 3        "Datsun 710" "22.8"
#> 4    "Hornet 4 Drive" "21.4"
#> 5 "Hornet Sportabout" "18.7"
#> 6           "Valiant" "18.1"

reprex包 (v0.3.0)创建于2021-05-07