twitteR 和 R 的 Twitter 表情符号编码问题
Twitter emoji encoding problems with twitteR and R
我正在尝试建立一种在 Twitter 中查找表情符号并将它们与可以在 unicode.org 中找到的 unicode table 相关联的方法,但我发现很难识别它们,因为我认为是编码问题或仅仅是我对这个话题的误解。简而言之,我所做的是从 http://www.unicode.org/emoji/charts/full-emoji-list.html 中找到的 table 构建一个 "library" 表情符号,其中包含表情符号的标题和代码点(代码)。我在 R 中用库 rvest.
废弃了这个
当我使用 R 中的 twitteR API 从 Twitter 获取信息时,问题就来了。因为表情符号的代码看起来完全不像 table 中的代码。
让我们以 100(一百分)红色图标的表情符号为例。这是之前链接中的数字 1468 table,它的代码点代码是:
U+1F4AF
现在,当我从 Twitter 上抓取它时,首先它在状态 class 中显示如下,API 已内置用于处理推文。
\xed��\xed��
然后,一旦我将它转换为数据帧,我也使用来自 Twitter API 的内置函数来完成它。例如:
tweet$toDataFrame()
表情变成这样:
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
我尝试用R中的函数iconv进行转换,代码如下:
iconv(tweet$text, from="UTF-8", to="ASCII", "byte)
我只设法让它看起来像这样:
<ed><a0><bd><ed><b2><af>
因此,在我的测试结束时,我得到了以下结果:
<ed><a0><bd><ed><b2><af>
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
\xed��\xed��
None 其中看起来像 table:
指定的代码点
U+1F4AF
有没有可能在两个字符串之间进行转换?
我错过了什么?为什么 Twitter 返回表情符号的信息?
请尝试输入:iconv(tweet$text, "latin1", "ASCII", sub="")
你那里也有类似的讨论:
Emoticons in Twitter Sentiment Analysis in r
此致,
玛格达
我以前对指挥一无所知,但经过几天的阅读,我想我知道发生了什么。我不太明白表情符号的编码是如何工作的,但我偶然发现了同样的问题并解决了它。
您想将 \xed��\xed��
映射到它的 name-decoded 版本:100 点。一个明智的方法可能是在线搜集字典并使用一个键(例如 Unicode)来替换它。在这种情况下,它将是 U+1F4AF
。
您显示的转换不是不同的编码,而是相同编码表情符号的不同表示法:
as.data.frame(tweet)
returns <ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
.
iconv(tweet, from="UTF-8", to="ASCII", "byte")
returns <ed><a0><bd><ed><b2><af>
.
所以直接使用 Unicode 是不可行的。另一种方法是使用已经以 <ed>...<ed>...
方式对表情符号进行编码的字典,例如此处的方式:emoji list。瞧!只有她的清单不完整,因为它来自
包含较少表情符号的字典。
快速的解决方案是简单地抓取一个更完整的词典并将<ed>...<ed>...
与其相应的英文文本翻译映射。我已经这样做了 posted here.
虽然没有其他人发布具有正确编码的列表这一事实让我很烦恼。事实上,我发现的大多数词典都使用 UTF-8 编码,而不是 <ed>...<ed>...
表示,而是 <f0>...
。事实证明,它们都是相同 unicode U+1F4AF
的正确 UTF-8 编码,只是字节的读取方式不同。
长答案。推文以 UTF-16 格式读取,然后转换为 UTF-8,这里是转换出现分歧的地方。当按字节对读取时,结果将是 UTF-8 <ed>...<ed>...
,当按四个字节的块读取时,结果将是 UTF-8 <f0>...
(这是为什么?我不完全理解,但我怀疑这与你的处理器的架构有关。
因此,解决问题的一种较慢(但更有意识)的方法是抓取 <f0>...
字典,将其转换为 UTF-16,然后成对将其转换回 UTF-8,然后您将结束最多有两个 <ed>...
。这两个 <ed>...
被称为 Unicode U+xxxxx
的 low-high 代理对表示。
举个例子:
unicode <- 0x1F4Af
# Multibyte Version
intToUtf8(unicode)
# Byte-pair Version
hilo <- unicode2hilo(unicode)
intToUtf8(hilo)
Returns:
[1] "\xf0\u009f\u0092�"
[1] "\xed��\xed��"
同样,使用 iconv(..., 'utf-8', 'latin1', 'byte')
与:
相同
[1] "<f0><9f><92><af>"
[1] "<ed><a0><bd><ed><b2><af>"
PS1.:
函数 unicode2hilo
是 hi-lo 到 unicode
的简单线性变换
unicode2hilo <- function(unicode){
hi = floor((unicode - 0x10000)/0x400) + 0xd800
lo = (unicode - 0x10000) + 0xdc00 - (hi-0xd800)*0x400
hilo = paste('0x', as.hexmode(c(hi,lo)), sep = '')
return(hilo)
}
hilo2unicode <- function(hi,lo){
unicode = (hi - 0xD800) * 0x400 + lo - 0xDC00 + 0x10000
unicode = paste('0x', as.hexmode(unicode), sep = '')
return(unicode)
}
PS2.:
我建议使用 iconv(tweet, 'UTF-8', 'latin1', 'byte')
来保留像 áäà 这样的特殊字符。
PS3.:
要将表情符号替换为其英文文本、标签、散列或任何您想将其映射到的内容,我建议在表情符号图表中使用 DFS,因为有些表情符号的 unicode 是其他更简单的 unicode 的串联(即 <f0><9f><a4><b8><e2><80><8d><e2><99><82><ef><b8><8f>
是人侧手翻,而独立的<f0><9f><a4><b8>
是人侧手翻,<e2><80><8d>
什么都不是,<e2><99><82>
是 男性标志 ,而 <ef><b8><8f>
什么都不是)而 男人侧手翻 和 男人侧手翻男性标志 语义上明显相关,我更喜欢更忠实的翻译。
Felipe Suárez Colmenares 提供的答案非常好,因为它描述了这个问题的机制,但我想指出你 here,这是我用 < ed > R 编码专门为推特。我还有关于如何浏览和识别表情符号散文版本的代码。认为这对于将来遇到此问题的人来说可能更容易。该词典是最新的 Unicode 版本 (9),一旦更新的版本出现,我也会更新它。
我正在尝试建立一种在 Twitter 中查找表情符号并将它们与可以在 unicode.org 中找到的 unicode table 相关联的方法,但我发现很难识别它们,因为我认为是编码问题或仅仅是我对这个话题的误解。简而言之,我所做的是从 http://www.unicode.org/emoji/charts/full-emoji-list.html 中找到的 table 构建一个 "library" 表情符号,其中包含表情符号的标题和代码点(代码)。我在 R 中用库 rvest.
废弃了这个当我使用 R 中的 twitteR API 从 Twitter 获取信息时,问题就来了。因为表情符号的代码看起来完全不像 table 中的代码。
让我们以 100(一百分)红色图标的表情符号为例。这是之前链接中的数字 1468 table,它的代码点代码是:
U+1F4AF
现在,当我从 Twitter 上抓取它时,首先它在状态 class 中显示如下,API 已内置用于处理推文。
\xed��\xed��
然后,一旦我将它转换为数据帧,我也使用来自 Twitter API 的内置函数来完成它。例如:
tweet$toDataFrame()
表情变成这样:
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
我尝试用R中的函数iconv进行转换,代码如下:
iconv(tweet$text, from="UTF-8", to="ASCII", "byte)
我只设法让它看起来像这样:
<ed><a0><bd><ed><b2><af>
因此,在我的测试结束时,我得到了以下结果:
<ed><a0><bd><ed><b2><af>
<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
\xed��\xed��
None 其中看起来像 table:
指定的代码点U+1F4AF
有没有可能在两个字符串之间进行转换? 我错过了什么?为什么 Twitter 返回表情符号的信息?
请尝试输入:iconv(tweet$text, "latin1", "ASCII", sub="")
你那里也有类似的讨论: Emoticons in Twitter Sentiment Analysis in r
此致, 玛格达
我以前对指挥一无所知,但经过几天的阅读,我想我知道发生了什么。我不太明白表情符号的编码是如何工作的,但我偶然发现了同样的问题并解决了它。
您想将 \xed��\xed��
映射到它的 name-decoded 版本:100 点。一个明智的方法可能是在线搜集字典并使用一个键(例如 Unicode)来替换它。在这种情况下,它将是 U+1F4AF
。
您显示的转换不是不同的编码,而是相同编码表情符号的不同表示法:
as.data.frame(tweet)
returns<ed><U+00A0><U+00BD><ed><U+00B2><U+00AF>
.iconv(tweet, from="UTF-8", to="ASCII", "byte")
returns<ed><a0><bd><ed><b2><af>
.
所以直接使用 Unicode 是不可行的。另一种方法是使用已经以 <ed>...<ed>...
方式对表情符号进行编码的字典,例如此处的方式:emoji list。瞧!只有她的清单不完整,因为它来自
包含较少表情符号的字典。
快速的解决方案是简单地抓取一个更完整的词典并将<ed>...<ed>...
与其相应的英文文本翻译映射。我已经这样做了 posted here.
虽然没有其他人发布具有正确编码的列表这一事实让我很烦恼。事实上,我发现的大多数词典都使用 UTF-8 编码,而不是 <ed>...<ed>...
表示,而是 <f0>...
。事实证明,它们都是相同 unicode U+1F4AF
的正确 UTF-8 编码,只是字节的读取方式不同。
长答案。推文以 UTF-16 格式读取,然后转换为 UTF-8,这里是转换出现分歧的地方。当按字节对读取时,结果将是 UTF-8 <ed>...<ed>...
,当按四个字节的块读取时,结果将是 UTF-8 <f0>...
(这是为什么?我不完全理解,但我怀疑这与你的处理器的架构有关。
因此,解决问题的一种较慢(但更有意识)的方法是抓取 <f0>...
字典,将其转换为 UTF-16,然后成对将其转换回 UTF-8,然后您将结束最多有两个 <ed>...
。这两个 <ed>...
被称为 Unicode U+xxxxx
的 low-high 代理对表示。
举个例子:
unicode <- 0x1F4Af
# Multibyte Version
intToUtf8(unicode)
# Byte-pair Version
hilo <- unicode2hilo(unicode)
intToUtf8(hilo)
Returns:
[1] "\xf0\u009f\u0092�"
[1] "\xed��\xed��"
同样,使用 iconv(..., 'utf-8', 'latin1', 'byte')
与:
[1] "<f0><9f><92><af>"
[1] "<ed><a0><bd><ed><b2><af>"
PS1.:
函数 unicode2hilo
是 hi-lo 到 unicode
unicode2hilo <- function(unicode){
hi = floor((unicode - 0x10000)/0x400) + 0xd800
lo = (unicode - 0x10000) + 0xdc00 - (hi-0xd800)*0x400
hilo = paste('0x', as.hexmode(c(hi,lo)), sep = '')
return(hilo)
}
hilo2unicode <- function(hi,lo){
unicode = (hi - 0xD800) * 0x400 + lo - 0xDC00 + 0x10000
unicode = paste('0x', as.hexmode(unicode), sep = '')
return(unicode)
}
PS2.:
我建议使用 iconv(tweet, 'UTF-8', 'latin1', 'byte')
来保留像 áäà 这样的特殊字符。
PS3.:
要将表情符号替换为其英文文本、标签、散列或任何您想将其映射到的内容,我建议在表情符号图表中使用 DFS,因为有些表情符号的 unicode 是其他更简单的 unicode 的串联(即 <f0><9f><a4><b8><e2><80><8d><e2><99><82><ef><b8><8f>
是人侧手翻,而独立的<f0><9f><a4><b8>
是人侧手翻,<e2><80><8d>
什么都不是,<e2><99><82>
是 男性标志 ,而 <ef><b8><8f>
什么都不是)而 男人侧手翻 和 男人侧手翻男性标志 语义上明显相关,我更喜欢更忠实的翻译。
Felipe Suárez Colmenares 提供的答案非常好,因为它描述了这个问题的机制,但我想指出你 here,这是我用 < ed > R 编码专门为推特。我还有关于如何浏览和识别表情符号散文版本的代码。认为这对于将来遇到此问题的人来说可能更容易。该词典是最新的 Unicode 版本 (9),一旦更新的版本出现,我也会更新它。