【问题标题】:dplyr filter condition to distinguish between unicode symbol and its unicode representationdplyr 过滤条件来区分 unicode 符号及其 unicode 表示
【发布时间】:2020-06-30 03:31:43
【问题描述】:

我正在尝试根据其是否为 \uxxxx 形式来过滤符号列

这在视觉上很容易,即有些看起来像$¢£,而另一些看起来像\u058f\u060b\u07fe

但我似乎无法使用 stringi / dplyr 弄清楚它

library(dplyr)
library(stringi)

df <- structure(list(Character = c("\\u0024", "\\u00A2", "\\u00A3", 
                             "\\u00A4", "\\u00A5", "\\u058F", "\\u060B", "\\u07FE", "\\u07FF", 
                             "\\u09F2", "\\u09F3", "\\u09FB", "\\u0AF1", "\\u0BF9", "\\u0E3F", 
                             "\\u17DB", "\\u20A0", "\\u20A1", "\\u20A2", "\\u20A3"), 
                     Symbol = c("$", "¢", "£", "¤", "¥", "\u058f", "\u060b", "\u07fe", "\u07ff", 
                                "৲", "৳", "\u09fb", "\u0af1", "\u0bf9", "฿", "៛", "₠", 
                                "₡", "₢", "₣")), row.names = c(NA, 20L), class = "data.frame")

   Character Symbol
1    \\u0024      $
2    \\u00A2      ¢
3    \\u00A3      £
4    \\u00A4      ¤
5    \\u00A5      ¥
6    \\u058F \u058f
7    \\u060B \u060b
8    \\u07FE \u07fe
9    \\u07FF \u07ff
10   \\u09F2      ৲
11   \\u09F3      ৳
12   \\u09FB \u09fb
13   \\u0AF1 \u0af1
14   \\u0BF9 \u0bf9
15   \\u0E3F      ฿
16   \\u17DB      ៛
17   \\u20A0      ₠
18   \\u20A1      ₡
19   \\u20A2      ₢
20   \\u20A3      ₣

我尝试过的

我曾尝试在 nchar 上使用变体,但没有运气


df$Symbol %>% nchar
# [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

df$Symbol %>% stri_unescape_unicode %>% nchar
# [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

df$Symbol %>% stri_escape_unicode %>% nchar
# [1] 1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

问题

如何在符号列中过滤$¢£ 等形式的所有行(反之,对于\u058f\u060b\u07fe 等行)?

【问题讨论】:

  • 在这种情况下您是否尝试过使用正则表达式?
  • @vpz 我没有,不。我推断会有一些“更正式”的方式来做这件事,但如果它可靠地工作,我会很乐意使用正则表达式!
  • 字符表示是否有一些符号模式?
  • @vpz 唯一的信息是 Symbol 列中包含的内容(我觉得它应该就足够了,但我不知道如何区分 - 哪个很有趣,因为它很容易被人眼看到)
  • 您可以使用 utf8::utf8_valid() 但这可能无法区分现有的有效 unicode 和有效但未分配的 unicode。你能稍微扩展一下你最终想要实现的目标吗?

标签: r dplyr stringr stringi


【解决方案1】:

编辑:

gdtools 包中的函数glyphs_match() 就是为此而设计的,但是,使用它并不能完全返回预期的结果。我使用Lucida Console 作为我的字体并在使用glyphs_match() 时获得以下输出。似乎有一个字形没有被渲染,但函数返回TRUE。也许其他用户可以解释为什么会这样。

df$glyph_match <- gdtools::glyphs_match(df$Symbol, fontfile = "C:\\WINDOWS\\Fonts\\lucon.TTF")
    df

   Character   Symbol glyph_match
1    \\u0024        $        TRUE
2    \\u00A2        ¢        TRUE
3    \\u00A3        £        TRUE
4    \\u00A4        ¤        TRUE
5    \\u00A5        ¥        TRUE
6    \\u058F <U+058F>       FALSE
7    \\u060B <U+060B>       FALSE
8    \\u07FE <U+07FE>       FALSE
9    \\u07FF <U+07FF>       FALSE
10   \\u09F2 <U+09F2>       FALSE
11   \\u09F3 <U+09F3>       FALSE
12   \\u09FB <U+09FB>       FALSE
13   \\u0AF1 <U+0AF1>       FALSE
14   \\u0BF9 <U+0BF9>       FALSE
15   \\u0E3F <U+0E3F>       FALSE
16   \\u17DB <U+17DB>       FALSE
17   \\u20A0 <U+20A0>       FALSE
18   \\u20A1        ¢        TRUE
19   \\u20A2 <U+20A2>       FALSE
20   \\u20A3 <U+20A3>        TRUE

较早的答案 - 可能仅适用于 Windows:

会根据您的字体/系统而有所不同,例如,当运行您的代码时,我的输出与您提供的不匹配:

df <- structure(list(Character = c("\\u0024", "\\u00A2", "\\u00A3", 
                             "\\u00A4", "\\u00A5", "\\u058F", "\\u060B", "\\u07FE", "\\u07FF", 
                             "\\u09F2", "\\u09F3", "\\u09FB", "\\u0AF1", "\\u0BF9", "\\u0E3F", 
                             "\\u17DB", "\\u20A0", "\\u20A1", "\\u20A2", "\\u20A3"), 
                     Symbol = c("$", "¢", "£", "¤", "¥", "\u058f", "\u060b", "\u07fe", "\u07ff", 
                                "৲", "৳", "\u09fb", "\u0af1", "\u0bf9", "฿", "៛", "₠", 
                                "₡", "₢", "₣")), row.names = c(NA, 20L), class = "data.frame")

df
   Character   Symbol
1    \\u0024        $
2    \\u00A2        ¢
3    \\u00A3        £
4    \\u00A4        ¤
5    \\u00A5        ¥
6    \\u058F <U+058F>
7    \\u060B <U+060B>
8    \\u07FE <U+07FE>
9    \\u07FF <U+07FF>
10   \\u09F2 <U+09F2>
11   \\u09F3 <U+09F3>
12   \\u09FB <U+09FB>
13   \\u0AF1 <U+0AF1>
14   \\u0BF9 <U+0BF9>
15   \\u0E3F <U+0E3F>
16   \\u17DB <U+17DB>
17   \\u20A0 <U+20A0>
18   \\u20A1        ¢
19   \\u20A2 <U+20A2>
20   \\u20A3 <U+20A3>

但如果字形存在,一种粗略的捕获方法是:

 nchar(capture.output(cat(df$Symbol, sep = "\n"))) == 1

[1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[18]  TRUE FALSE FALSE

所以字形可以通过以下方式过滤:

library(dplyr)

df %>%
  filter(nchar(capture.output(cat(Symbol, sep = "\n"))) == 1)

  Character Symbol
1   \\u0024      $
2   \\u00A2      ¢
3   \\u00A3      £
4   \\u00A4      ¤
5   \\u00A5      ¥
6   \\u20A1      ¢

【讨论】:

    【解决方案2】:

    使用as.character.POSIXt 来“渲染”符号并用空格填充。 "\uxxxx" 形式的 Unicode 字符将打印为单个字符,所有其他字符将更大;然后可以根据长度过滤:

    # To keep 'single char' symbols e.g. "$":
    df %>% filter(nchar(as.character.POSIXt(Symbol)) >= 2)
    
    # Or for 'unicode format' symbols e.g. "\u07fe":
    df %>% filter(nchar(as.character.POSIXt(Symbol)) == 1)
    

    如果您有一个长字符串作为“符号”(例如“aaaaaaaaaa₣”),则填充将增加并且需要考虑例如

    # To keep 'single char' symbols e.g. "$":
    df %>% filter(nchar(as.character.POSIXt(Symbol)) >= 11)
    
    # Or for 'unicode format' symbols e.g. "\u07fe":
    df %>% filter(nchar(as.character.POSIXt(Symbol)) <= 10)
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-21
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 2012-08-15
      • 2023-04-04
      相关资源
      最近更新 更多