dplyr 过滤条件以区分 unicode 符号及其 unicode 表示

dplyr filter condition to distinguish between unicode symbol and its unicode representation

我正在尝试根据它是否为 \uxxxx

形式来过滤 Symbol 列

这在视觉上很容易,即有些看起来像 $¢£,有些像 \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

问题

我如何在 Symbol 列上过滤所有格式为 $¢£ 等的行(反之,如 \u058f\u058f\u060b, \u07fe)?

编辑:

gdtools 包中的函数 glyphs_match() 就是为此而设计的,但是,使用它并没有 return 预期的结果。我使用 Lucida Console 作为我的字体,并在使用 glyphs_match() 时获得以下输出。似乎有一个字形未呈现,但函数 returns 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:

根据您的 font/system 会有不同,例如,当 运行 您的代码我的输出与您提供的不匹配时:

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      ¢

使用as.character.POSIXt到'render'符号并用空格填充。 “\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)

如果您有一个长字符串作为 'symbol'(例如 "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)