来自不同数据文件的相同字符串在 R 中不匹配
identical strings from different data files won't match in R
我正在合并一些文件,但两个文件不会合并 - 尽管有一个匹配的键列(我实际上是通过复制粘贴另一个键列生成的)。这是最该死的事情,我担心我要么发疯了,要么错过了一些基本的东西。作为一个例子(我无法弄清楚如何使它可重现,因为当我将这些字符串复制并粘贴到新对象中时,它们比较得很好),这是我当前的控制台:
> q
[1] "1931 80th Anniversary"
> z
[1] "1931 80th Anniversary"
> q == z
[1] FALSE
我对两者都进行了 str-ed,以防万一我遗漏了什么,并且...
> str(q)
chr "1931 80th Anniversary"
> str(z)
chr "1931 80th Anniversary"
这里可能发生了什么?
这是一款很棒的益智游戏。要回答 - 诊断问题,charToRaw()
就是答案。
> charToRaw(q)
[1] 31 39 33 31 c2 a0 38 30 74 68 c2 a0 41 6e 6e 69 76 65
[19] 72 73 61 72 79
> charToRaw(z)
[1] 31 39 33 31 20 38 30 74 68 20 41 6e 6e 69 76 65 72 73
[19] 61 72 79
哦!不同的!它似乎在于编码,考虑到这些都是我从中加载的普通 ole' CSV,我永远不会猜到,但是
> Encoding(q)
[1] "UTF-8"
> Encoding(z)
[1] "unknown"
最后,我在q上用了iconv()
让它生效
> iconv(q, from = 'UTF-8', to = 'ASCII//TRANSLIT') == z
[1] TRUE
这是一段奇怪的旅程,我希望这对像我一样困惑的其他人有所帮助 - 他们在此过程中学到了一些新功能。
您的字符串中似乎有 non-breaking space,这并不是真正的编码问题。这种情况一直发生在我身上,因为 alt + space 在 Mac 上插入了 non-breaking space,我在德语键盘上使用 alt 来输入各种特殊字符,也。我的小指是我最慢的手指,当我从一些特殊字符过渡到 space 时,它们并不总是能足够快地释放 alt。我在编写 bash 脚本时发现了这个问题,其中 <command> | <command>
很常见,而 |
是 alt + 7.
我认为 stringr::str_replace_all(q, "\s", " ")
应该可以解决您当前的问题。或者,您可以尝试定位特定 non-printables,例如在你的情况 stringr::str_replace_all(q, "\uA0", " ")
。要暴露违规字符,您可以使用 stringi::stri_escape_unicode(q)
,这将 return "1931\u00a080th\u00a0Anniversary"
。然后,您只需复制并粘贴即可获得与上述相同的结果:stringr::str_replace_all(q, "\u00a0", " ")
我正在合并一些文件,但两个文件不会合并 - 尽管有一个匹配的键列(我实际上是通过复制粘贴另一个键列生成的)。这是最该死的事情,我担心我要么发疯了,要么错过了一些基本的东西。作为一个例子(我无法弄清楚如何使它可重现,因为当我将这些字符串复制并粘贴到新对象中时,它们比较得很好),这是我当前的控制台:
> q
[1] "1931 80th Anniversary"
> z
[1] "1931 80th Anniversary"
> q == z
[1] FALSE
我对两者都进行了 str-ed,以防万一我遗漏了什么,并且...
> str(q)
chr "1931 80th Anniversary"
> str(z)
chr "1931 80th Anniversary"
这里可能发生了什么?
这是一款很棒的益智游戏。要回答 - 诊断问题,charToRaw()
就是答案。
> charToRaw(q)
[1] 31 39 33 31 c2 a0 38 30 74 68 c2 a0 41 6e 6e 69 76 65
[19] 72 73 61 72 79
> charToRaw(z)
[1] 31 39 33 31 20 38 30 74 68 20 41 6e 6e 69 76 65 72 73
[19] 61 72 79
哦!不同的!它似乎在于编码,考虑到这些都是我从中加载的普通 ole' CSV,我永远不会猜到,但是
> Encoding(q)
[1] "UTF-8"
> Encoding(z)
[1] "unknown"
最后,我在q上用了iconv()
让它生效
> iconv(q, from = 'UTF-8', to = 'ASCII//TRANSLIT') == z
[1] TRUE
这是一段奇怪的旅程,我希望这对像我一样困惑的其他人有所帮助 - 他们在此过程中学到了一些新功能。
您的字符串中似乎有 non-breaking space,这并不是真正的编码问题。这种情况一直发生在我身上,因为 alt + space 在 Mac 上插入了 non-breaking space,我在德语键盘上使用 alt 来输入各种特殊字符,也。我的小指是我最慢的手指,当我从一些特殊字符过渡到 space 时,它们并不总是能足够快地释放 alt。我在编写 bash 脚本时发现了这个问题,其中 <command> | <command>
很常见,而 |
是 alt + 7.
我认为 stringr::str_replace_all(q, "\s", " ")
应该可以解决您当前的问题。或者,您可以尝试定位特定 non-printables,例如在你的情况 stringr::str_replace_all(q, "\uA0", " ")
。要暴露违规字符,您可以使用 stringi::stri_escape_unicode(q)
,这将 return "1931\u00a080th\u00a0Anniversary"
。然后,您只需复制并粘贴即可获得与上述相同的结果:stringr::str_replace_all(q, "\u00a0", " ")