เงื่อนไขตัวกรอง dplyr เพื่อแยกความแตกต่างระหว่างสัญลักษณ์ยูนิโค้ดและการแทนยูนิโค้ด


10

ฉันพยายามกรองคอลัมน์สัญลักษณ์โดยพิจารณาว่าเป็นของแบบฟอร์มหรือไม่ \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)?


คุณลองใช้ Regex ในกรณีนี้หรือไม่?
vpz

@vpz ฉันไม่ได้ไม่ ฉันคิดว่าจะมีวิธีที่ 'เป็นทางการ' มากกว่านี้ แต่จะใช้ regex ถ้ามันทำงานได้อย่างน่าเชื่อถือ!
สตีฟ

การแสดงตัวอักษรมีรูปแบบบางอย่างสำหรับสัญลักษณ์หรือไม่?
vpz

@vpz ข้อมูลเพียงอย่างเดียวคือสิ่งที่มีอยู่ในSymbolคอลัมน์ (ฉันรู้สึกว่ามันควรจะเพียงพอ แต่ฉันไม่สามารถแยกแยะวิธีการแยกแยะได้ - ซึ่งน่าสนใจเพราะมันเป็นเรื่องง่ายสำหรับสายตาของมนุษย์ที่จะเห็น)
stevec

1
คุณสามารถใช้utf8::utf8_valid()แต่สิ่งนี้อาจไม่แยกความแตกต่างระหว่าง unicode ที่ถูกต้องที่มีอยู่และ unicode ที่ถูกต้อง แต่ไม่ได้กำหนด คุณสามารถขยายสิ่งเล็ก ๆ น้อย ๆ ในสิ่งที่คุณพยายามจะบรรลุในที่สุด?
วันที่ 1

คำตอบ:


7

แก้ไข:

ฟังก์ชั่นglyphs_match()จากgdtoolsแพ็คเกจได้รับการออกแบบมาสำหรับสิ่งนี้อย่างไรก็ตามการใช้มันไม่ได้ผลตามที่คาดหวัง ฉันใช้เป็นตัวอักษรของฉันและได้รับผลลัพธ์ต่อไปนี้เมื่อใช้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>

แต่วิธีการจับหยาบคายอย่างเดียวถ้ามี glyph อยู่:

 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เพื่อ 'แสดง' สัญลักษณ์และแผ่นที่มีช่องว่าง อักขระ Unicode ในรูปแบบ "\ uxxxx" จะถูกพิมพ์เป็นอักขระเดียวและอักขระอื่นทั้งหมดจะมีขนาดใหญ่กว่า จากนั้นคุณสามารถกรองตามความยาว:

# 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.