如何修剪前导和尾随空格?

时间:2010-02-14 12:44:03

标签: r whitespace trim removing-whitespace built-in

我在data.frame中有前导和尾随空格的麻烦。 例如,我想根据特定条件查看row中的特定data.frame

> 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?
  3. 中的前导和尾随空格

    到目前为止,我曾经编写过一个简单的Perl脚本来删除空格,但如果我能以某种方式在R中执行它会很好。

15 个答案:

答案 0 :(得分:483)

从R 3.2.0开始,引入了一个用于删除前导/尾随空格的新函数:

trimws()

请参阅:http://stat.ethz.ch/R-manual/R-patched/library/base/html/trimws.html

答案 1 :(得分:433)

可能最好的方法是在读取数据文件时处理尾随空格。如果您使用read.csvread.table,则可以设置参数strip.white=TRUE

如果您想在之后清理字符串,可以使用以下功能之一:

# returns string w/o leading whitespace
trim.leading <- function (x)  sub("^\\s+", "", x)

# returns string w/o trailing whitespace
trim.trailing <- function (x) sub("\\s+$", "", x)

# returns string w/o leading or trailing whitespace
trim <- function (x) gsub("^\\s+|\\s+$", "", x)

myDummy$country上使用其中一项功能:

 myDummy$country <- trim(myDummy$country)

要“显示”您可以使用的空格:

 paste(myDummy$country)

将显示由引号(“)包围的字符串,使空格更容易被发现。

答案 2 :(得分:83)

要操纵空格,请在stringr包中使用str_trim()。 该软件包的手册日期为2013年2月15日,并且在CRAN中。 该函数还可以处理字符串向量。

install.packages("stringr", dependencies=TRUE)
require(stringr)
example(str_trim)
d4$clean2<-str_trim(d4$V2)

(归功于评论者:R。Cotton)

答案 3 :(得分:22)

一个简单的函数,用于删除前导空格和尾随空格:

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

<强>用法:

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

答案 4 :(得分:10)

ad1)要查看空格,您可以使用修改过的参数直接调用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

答案 5 :(得分:8)

使用grep或grepl查找带有空格和子的观察结果以消除它们。

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"  

答案 6 :(得分:5)

我更愿意将答案添加为对用户56的评论,但却无法写作独立答案。 删除前导和尾随空白也可以通过gdata包中的trim()函数来实现:

require(gdata)
example(trim)

用法示例:

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

答案 7 :(得分:5)

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

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

仅删除前导空格,请使用stri_trim_left。要仅删除尾随空格,请使用stri_trim_right。如果要删除其他前导或尾随字符,则必须使用pattern =指定。

有关详细信息,另请参阅?stri_trim

答案 8 :(得分:4)

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

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

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

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

请注意,如果在开头有匹配项 一个(非空)字符串,输出的第一个元素是'&#34;&#34;',但是 如果字符串末尾有匹配,则输出为 与删除的比赛相同。

答案 9 :(得分:1)

我创建了一个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"   

答案 10 :(得分:1)

最佳方法是trimws()

以下代码将此函数应用于整个数据框

  

mydataframe&lt; - data.frame(lapply(mydataframe,trimws),stringsAsFactors = FALSE)

答案 11 :(得分:1)

我尝试过trim()。适用于空格以及'\ n'。 x ='\ n Harden,J. \ n'

修剪(x)

答案 12 :(得分:0)

myDummy[myDummy$country == "Austria "] <- "Austria"

在此之后,你需要强制R不要将“奥地利”识别为一个级别。让我们假装你也有“美国”和“西班牙”作为等级:

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

比最高投票反应少一点恐吓,但它应该仍然有用。

答案 13 :(得分:0)

对于谁可能感兴趣,这里是一个简单的基准测试。这当然没有捕获所有奇怪的情况,但到目前为止,我们仍然缺少 str_trim 删除空格而 trimws 没有 (see Richard Telford's comment to this answer) 的示例。似乎无关紧要 - gsub 选项似乎是最快的 :)

x <- c(" lead", "trail ", " both ", " both and middle ", " _special")
gsub_trim <- function (x) gsub("^\\s+|\\s+$", "", x)
res <- microbenchmark::microbenchmark(
  gsub = gsub_trim(x),
  trimws = trimws(x),
  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)

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  

答案 14 :(得分: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 package (v0.3.0) 于 2021 年 5 月 7 日创建