【问题标题】:Multiple patterns and replacements from "dictionary" dataframe in R, maybe with gsub?R中“字典”数据帧的多种模式和替换,也许是gsub?
【发布时间】:2021-12-25 13:44:40
【问题描述】:

我有一个包含表情符号名称而不是实际图像的字符串 (data$text) 的数据集(例如,FACE_WITH_TEARS_OF_JOY)。现在我正在尝试用实际的表情符号替换每个表情符号名称。名称和表情符号保存在一个额外的数据集中,用作“字典”(emojis$nameemojis$emoji)。

这是我的数据集:

data <- structure(list(text = c("blabla HUGGING_FACE PARTY_POPPER", "bla FACE_WITH_TEARS_OF_JOY bla FACE_WITH_TEARS_OF_JOY", "PARTY_POPPER")), class = "data.frame", row.names = c(NA, -3L))

看起来像:

                                                   text
1                      blabla HUGGING_FACE PARTY_POPPER
2 bla FACE_WITH_TEARS_OF_JOY bla FACE_WITH_TEARS_OF_JOY
3                                          PARTY_POPPER

请注意,表情符号名称只是文本的一部分。文本的其余部分应保留。

这是我的“字典”:

emojis <- structure(list(name = c("FACE_WITH_TEARS_OF_JOY", "HUGGING_FACE", 
                                  "PARTY_POPPER"), emoji = c("\U0001f602", "\U0001f917", "\U0001f389"
                                  )), class = "data.frame", row.names = c(NA, -3L))

看起来像:

                    name      emoji
1 FACE_WITH_TEARS_OF_JOY \U0001f602
2           HUGGING_FACE \U0001f917
3           PARTY_POPPER \U0001f389

对于单个表情符号,此代码有效:

data$text <- gsub("FACE_WITH_TEARS_OF_JOY", "\U0001f602", data$text)

结果是:

                              text
1 blabla HUGGING_FACE PARTY_POPPER
2    bla \U0001f602 bla \U0001f602
3                     PARTY_POPPER

但是,我也想替换其他表情符号名称。结果应该是:

                           text
1  blabla \U0001f917 \U0001f389
2 bla \U0001f602 bla \U0001f602
3                    \U0001f389

由于有成千上万的表情符号,我需要类似的东西:

data$text <- gsub(emojis$name, emojis$emoji, data$text)

这不起作用(错误:“参数'模式'的长度> 1,只有第一个元素将使用数字”)我自己找不到解决方案。

提前致谢!

【问题讨论】:

  • 请阅读r标签页面顶部的信息,并特别注意需要最少但完整的可重现代码和输入(使用dput)。由于缺少输入,任何人都无法运行此代码。
  • 感谢您现在允许我 - 我已经编辑了问题,希望现在更好。

标签: r gsub string-substitution


【解决方案1】:

1) gsubfn 创建一个字典dict,其中包含一个列表,其名称是要替换的名称,其值是要替换它们的值。然后使用gsubfn 使用字典执行非空格字符串"\\S+" 的替换。 gsubfn 采用与 gsub 相同的参数,除了第二个参数可以是这样的列表(或某些其他对象)。

library(gsubfn)

dict <- with(emojis, setNames(as.list(emoji), name))
gsubfn("\\S+", dict, data$text)
## [1] "blabla ? ?"  "bla ? bla ?" "?"   

2) Base R 这使用Reduce 遍历emojis 的行,将它们一一替换。

gsub_ <- function(s, i) with(emojis[i, ], gsub(name, emoji, s))
Reduce(gsub_, init = data$text, 1:nrow(emojis))
## [1] "blabla ? ?"  "bla ? bla ?" "?"       

【讨论】:

    【解决方案2】:

    您可以在包plyr 中使用函数mapvalues。示例:

    library(plyr)
    
    # data
    data <- data.frame("ID" = 1:5, "text" = c("FACE_WITH_TEARS", "FACE_WITH_JOY",
                          "FACE_WITH_JOY", "FACE_WITH_PLAIN", "FACE_WITH_TEARS"))
    
    # "dictionary" 
    emojis <- data.frame("name" = c("FACE_WITH_TEARS", "FACE_WITH_JOY", "FACE_WITH_PLAIN"),
                         "emojis" = c("CRY", "HAPPY", "NUETRAL"))
    
    data$text <- mapvalues(data$text, emojis$name, emojis$emojis)
    
    data
    

    结果是

      ID    text
    1  1     CRY
    2  2   HAPPY
    3  3   HAPPY
    4  4 NUETRAL
    5  5     CRY
    

    【讨论】:

    • 非常感谢!这似乎仅在表情符号名称周围没有文字时才有效。例如,将“PARTY_POPPER”替换为“\U0001f389”,但不能将“blabla PARTY_POPPER”替换为“blabla \U0001f389”。对不起,我没有让我的问题更清楚。我现在已经编辑过了。
    【解决方案3】:

    您还可以使用 stringr::str_replace_allsetNames 从您的 emojis 数据框创建字典:

    data <- structure(list(text = c("blabla HUGGING_FACE PARTY_POPPER", "bla FACE_WITH_TEARS_OF_JOY bla FACE_WITH_TEARS_OF_JOY", "PARTY_POPPER")), class = "data.frame", row.names = c(NA, -3L))
    emojis <- structure(list(name = c("FACE_WITH_TEARS_OF_JOY", "HUGGING_FACE", 
                                      "PARTY_POPPER"), emoji = c("\U0001f602", "\U0001f917", "\U0001f389"
                                      )), class = "data.frame", row.names = c(NA, -3L))
    
    library(stringr)
    stringr::str_replace_all(data$text, setNames(emojis$emoji, emojis$name))
    

    请参阅online R demo

    输出:

    [1] "blabla ? ?"  "bla ? bla ?" "?" 
    

    【讨论】:

    • 也谢谢。与您的测试用例不同,在我的数据集中 str_replace_all 仅适用于表情符号名称周围没有文本的情况。例如,将“PARTY_POPPER”替换为“\U0001f389”,但不能将“blabla PARTY_POPPER”替换为“blabla \U0001f389”。对不起,我没有让我的问题更清楚。我现在已经对其进行了编辑并提供了一个可重现的数据集。
    • @just_asking 使用更新后的代码。
    猜你喜欢
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 2020-05-07
    相关资源
    最近更新 更多