修剪不起作用时如何修剪空白?

时间:2019-06-26 23:16:34

标签: r

我习惯使用trimws来消除文本上的任何空格。

现在我有一个使用废弃数据制作的df文件。

我有2列与金钱相关,但都是chr向量,因为它们是从网上刮来的,如前所述。我可以毫无问题地将trimws应用于其中一列,而对另一列则可以。

str(lacuracao_tvs$precio_actual[1])
chr " 1199.00"

为什么?

new_precio_actual <- trimws(lacuracao_tvs$precio_actual[1])

dput(new_precio_actual)
" 1199.00"

整理适用于precio_antes,但不适用于precio_actual:

> str(lacuracao_tvs)
'data.frame':   100 obs. of  4 variables:
 $ ecommerce    : chr  "la-curacao" "la-curacao" "la-curacao" "la-curacao" ...
 $ producto     : chr  "TV LED AOC Ultra HD Smart 50\" LE50U7970" "TV Samsung Ultra HD 4K Smart 58\" UN-58RU7100G" "TV LG Ultra HD 4K Smart AI 55\" 55UK6200" "TV AOC Ultra HD 4K Smart 55\" 55U6285" ...
 $ precio_antes : chr  "1899.00" "1899.00" "1899.00" "1899.00" ...
 $ precio_actual: chr  " 1199.00" " 1199.00" " 1199.00" " 1199.00" ...

SessionInfo:

Sys.info()
          sysname           release           version          nodename 
        "Windows"          "10 x64"     "build 17763" "DESKTOP-MNDUKBD" 
          machine             login              user    effective_user 
         "x86-64"       "OGONZALES"       "OGONZALES"       "OGONZALES" 
> sessionInfo(package = NULL)
R version 3.5.2 (2018-12-20)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.7.8     rvest_0.3.2     xml2_1.2.0      RSelenium_1.7.5

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.0       rstudioapi_0.9.0 bindr_0.1.1      magrittr_1.5    
 [5] rappdirs_0.3.1   tidyselect_0.2.5 R6_2.3.0         rlang_0.3.1     
 [9] stringr_1.3.1    httr_1.4.0       caTools_1.17.1.1 tools_3.5.2     
[13] binman_0.1.1     selectr_0.4-1    semver_0.2.0     subprocess_0.8.3
[17] yaml_2.2.0       openssl_1.1      assertthat_0.2.0 tibble_2.0.1    
[21] crayon_1.3.4     bindrcpp_0.2.2   purrr_0.2.5      bitops_1.0-6    
[25] curl_3.3         glue_1.3.0       wdman_0.2.4      stringi_1.2.4   
[29] compiler_3.5.2   pillar_1.3.1     XML_3.98-1.20    jsonlite_1.6    
[33] pkgconfig_2.0.2

更新1:

utf8ToInt(lacuracao_tvs$precio_actual[1])
[1] 160  49  49  57  57  46  48  48

3 个答案:

答案 0 :(得分:7)

ASCII码为160的字符称为“不间断空格”,人们可以在Wikipedia上阅读它:

https://en.wikipedia.org/wiki/Non-breaking_space

trimws()函数未将其包含在该函数删除的字符列表中:

x <- intToUtf8(c(160,49,49,57,57,46,48,48))
x
#[1] " 1199.00"

trimws(x)
#[1] " 1199.00"

摆脱它的一种方法是使用 stringr 库中的str_trim()函数:

library(stringr)
y <- str_trim(x)
trimws(y)
[1] "1199.00"

通过首先应用iconv()函数的另一种方法:

y <- iconv(x, from = 'UTF-8', to = 'ASCII//TRANSLIT')
trimws(y)
#[1] "1199.00"

更新 为了解释为什么trimws()不能删除上述“不可见”字符而stringr:str_trim()可以删除字符。

这是我们从trimws()帮助中看到的内容:

  

为了便于携带,“空白”被用作字符类[   \ t \ r \ n](空格,水平制表符,换行符,回车符)

对于stringr:str_trim()帮助主题,它本身并未指定被视为“空白”的内容,但是如果您查看stri_trim_both所调用的str_trim()的帮助,则会看到:{ {1}} 基本上,在这种情况下,它使用的字符范围更广,被视为空白。

更新2

如@ H1所述,版本3.6.0提供了一个选项,用于指定要考虑的空白字符:

  

内部为'sub(re,“”,*,perl = TRUE)',即PCRE库   使用正则表达式。对于可移植性,默认   “空白”是字符类“ [\ t \ r \ n]”(空格,水平   标签,回车符,换行符)。另外,“ [\ h \ v]”是一个很好的选择   (PCRE)泛化以匹配所有Unicode水平和垂直   空白字符,另请参见https://www.pcre.org>。

因此,如果您使用的是3.6.0或更高版本,则只需执行以下操作:

stri_trim_both(str, pattern = "\\P{Wspace}")

答案 1 :(得分:1)

从R版本3.6.0 caught "com.firebase.core", "Default app has already been configured" 开始,有一个参数可以让您定义被认为是空白的空间,在这种情况下,它是一个不间断空格。

trimws()

答案 2 :(得分:0)

简答;使用 enc2native() 和 str_trim()

长答案;我遇到了一个问题,即数据库查询包含非 utf-8 编码文本,这导致了以下错误。

<块引用>

sub(re, "", x, perl = TRUE) 中的错误:输入字符串 5 是无效的 UTF-8

我最初使用包裹在 lapply 函数中的 utf8_encode ,但是这导致所有新行和输入字符被替换为 \r & \n 我发现这是不受欢迎的(注意,不包装它会将整个 df 转换为字符串) .

使用 enc2native(y) %>% str_trim() 避免了这种情况,但是为了将其应用于 df 我做了一个自定义函数。

    cleanDBO <- function(x){
      # Use enc2native as it will replace non utf8 characters with something 
      # readable and not replace \r, \n etc with text.
      x <- x %>% 
        lapply(., function(y) { 
          if(is.character(y)) enc2native(y)  %>% str_trim()
          else y }) %>% as_tibble()
    }

这使所有非字符列保持原样,没有 if else 所有列都转换为字符。