【问题标题】:trimws bug? leading whitespace not removed修剪错误?前导空格未删除
【发布时间】:2017-07-12 07:01:55
【问题描述】:

编辑:感谢 R Yoda,我终于能够针对我面临的问题创建一个可重现的示例:

x = rawToChar(as.raw(c(0xa0, 0x31, 0x31, 0x2e, 0x31, 0x33, 0x32, 0x35, 0x39, 0x32)))
trimws(x)

=> 问题:如何修剪 x?

问题的旧文本:
请参阅随附的屏幕截图。不幸的是,我无法创建可重现的示例,因为dput 正在影响结果...

任何人都知道如何调查 x 出了什么问题?前导空格似乎不是标准空格!

charToRaw(x) 给出 a0 31 31 2e 31 33 32 35 39 32
dput(charToRaw(x)) 给出 as.raw(c(0xa0, 0x31, 0x31, 0x2e, 0x31, 0x33, 0x32, 0x35, 0x39, 0x32))
Encoding(x) 给出 "unknown"(与 Encoding(" 11.132592") 相同)

【问题讨论】:

  • 无法在R 3.4.0中重现问题x <- " 11.132592"; trimws(x)# [1] "11.132592"
  • @akrun 我知道,令人沮丧!我的 R 3.3.2 和你一样。我如何调查为什么 x 与 dput 中的值不同?
  • @akrun,肯定是 R 3.2.2。但是您的代码不会重现该错误。检查我的屏幕截图:x gives "11.132592",但现在是这样定义的。
  • 可能是编码问题...如果您不能使用dput(为什么?)请至少在此处发布charToRaw(x)Encoding(x) 的输出,也许这说明了原因...
  • charToRaw(' ') 产生20x 的第一个字符是a0;因此它可能不被识别为空格

标签: r trim


【解决方案1】:

0xa0R 中编码另一种类型的空格(不间断空格),而0x20 是空格。
trimws 搜索空格、制表符、换行符或回车(由[ \t\r\n]+ 表示)但不适用于不间断空格,因此它不起作用。
您可以使用sub(抑制前导或尾随空格)或gsub(抑制尾随和前导空格)删除任何类型的尾随或前导空格(包括0xa0代表的空格) :

sub("^\\s+", "", x)
[1] "11.132592"

对于删除前导和尾随空格:

gsub("(^\\s+)|(\\s+$)", "", x)

【讨论】:

  • 谢谢!记录在案stringr::str_trim 也很好用
  • @RockScience 在stringr::str_trim 下有一个C 例程,我没有检查它,但我猜它会删除任何空间,这与trimws 相反;-)跨度>
  • 未来的读者来这里及以上gsub解决方案由于回车+换行空格(0xc2 0xa0)不起作用,请参阅此perl regex或此remove all/any space
【解决方案2】:

一种可能的解决方案是将错误编码的空格替换为正确的空格:

trimws(rawToChar(replace(x1, x1 == as.raw(0xa0), as.raw(0x20))))

给出:

[1] "11.132592"

要转换为数字,只需将上面的代码包装在as.numeric中即可。


使用过的数据:

x1 <- as.raw(c(0xa0, 0x31, 0x31, 0x2e, 0x31, 0x33, 0x32, 0x35, 0x39, 0x32))

【讨论】:

  • 不幸的是,这不是修剪。如果空格位于字符串的中间,则会产生问题。
  • @RockScience 这回答了所提出的问题。如果你没有问对正确的问题,那是你的责任。