điều kiện lọc dplyr để phân biệt giữa biểu tượng unicode và biểu diễn unicode của nó


10

Tôi đang cố gắng lọc cột Biểu tượng dựa trên việc nó có dạng không \uxxxx

Đây là dễ dàng trực quan, có nghĩa là, một số trông giống như $, ¢, £, và những người khác như \u058f, \u060b, \u07fe.

Nhưng tôi dường như không thể tìm ra nó bằng cách sử dụng 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      ₣

Những gì tôi đã thử

Tôi đã thử sử dụng các biến thể trên ncharnhưng không gặp may mắn


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

Câu hỏi

Làm thế nào tôi có thể lọc trên cột Symbol cho tất cả các hàng của hình thức $, ¢, £vv (và ngược lại cho các hàng thích \u058f, \u060b, \u07fe)?


Bạn đã thử sử dụng Regex trong trường hợp này?
vpz

@vpz Tôi chưa, không. Tôi nghĩ rằng sẽ có một số cách 'chính thức hơn' để làm điều đó, nhưng sẽ sẵn sàng sử dụng regex nếu nó hoạt động đáng tin cậy!
stevec

Liệu đại diện nhân vật có một số mô hình cho các biểu tượng?
vpz

@vpz các thông tin chỉ là những gì chứa trong Symbolcột (Tôi cảm thấy như nó nên là đủ, nhưng tôi không thể làm việc ra làm thế nào để phân biệt - đó là thú vị bởi vì nó rất dễ dàng cho đôi mắt con người để xem)
stevec

1
Bạn có thể sử dụng utf8::utf8_valid()nhưng điều này có thể không phân biệt giữa unicode hợp lệ hiện tại và unicode hợp lệ nhưng không được gán. Bạn có thể mở rộng một chút về những gì cuối cùng bạn đang cố gắng để đạt được?
H 1

Câu trả lời:


7

Biên tập:

Chức năng glyphs_match()từ gdtoolsgói được thiết kế cho việc này, tuy nhiên, sử dụng nó không hoàn toàn trả về kết quả mong đợi. Tôi đang sử dụng Lucida Consolelàm phông chữ của mình và có được đầu ra sau khi sử dụng glyphs_match(). Dường như có một glyph không được hiển thị nhưng hàm này trả về TRUE. Có lẽ những người dùng khác có thể giải thích tại sao lại như vậy.

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

Câu trả lời trước - chỉ có thể hoạt động trên Windows:

Sẽ có biến thể tùy thuộc vào phông chữ / hệ thống của bạn, ví dụ, khi chạy mã của bạn, đầu ra của tôi không khớp với những gì bạn đã cung cấp:

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>

Nhưng một cách thô sơ để nắm bắt nếu glyph tồn tại là:

 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

Vì vậy, glyphs có thể được lọc bằng cách:

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

Sử dụng as.character.POSIXtđể 'kết xuất' biểu tượng và pad với khoảng trắng. Các ký tự Unicode ở dạng "\ uxxxx" sẽ được in dưới dạng một ký tự và tất cả các ký tự khác sẽ lớn hơn; sau đó bạn có thể lọc theo độ dài:

# 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)

Nếu bạn có một chuỗi dài dưới dạng 'ký hiệu' (ví dụ: "aaaaaaaaaa ₣"), phần đệm sẽ được tăng lên và cần phải được tính đến, ví dụ:

# 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.