【问题标题】:R match key values vector with irregular strings vectorR将键值向量与不规则字符串向量匹配
【发布时间】:2016-03-23 17:15:24
【问题描述】:

我陷入了我一直试图在论坛中找到但没有成功的噩梦。所以我试试直接问的机会。

我有一个包含随机城市的不规则字符串的向量,我想从包含城市名称的键值向量中提取/标记每个不规则字符串。 例如,

Vector <- c("...the life in Paris is ...","In Roma, there is...","...nice weekend in New York with...")
Cities <- c("London","Paris","Madrid","Roma","New York")

对于Vector中的每一个字符串,都应该有一个来自Cities的对应值来对应。

一开始我在考虑使用循环,但是数据量使 R 搜索太长,我更想使用 grep 的一种矩阵计算,但我总是出错。

您知道这是否是正确的方法吗?

【问题讨论】:

    标签: r parsing vector split


    【解决方案1】:

    您可以使用sapplygrepl

    check_vec <- sapply(Cities, grepl, Vector)
    row.names(check_vec) <- Vector
    
    check_vec
    #                                    London Paris Madrid  Roma New York
    #...the life in Paris is ...          FALSE  TRUE  FALSE FALSE    FALSE
    #In Roma, there is...                 FALSE FALSE  FALSE  TRUE    FALSE
    #...nice weekend in New York with...  FALSE FALSE  FALSE FALSE     TRUE
    

    如果你需要每个向量的关键字:

    apply(check_vec, 1, function (x) colnames(check_vec)[which(x)])
    #        ...the life in Paris is ...                In Roma, there is... ...nice weekend in New York with... 
    #                            "Paris"                              "Roma"                          "New York" 
    

    编辑

    按照@nicola 的明智建议,为了更安全,您可以使用vapply 而不是sapply

    check_vec <- vapply(Cities, grepl, x=Vector, logical(length(Vector)))
    

    【讨论】:

    • 不错。我鼓励使用vapply 而不是sapplyvapply(Cities, grepl, x=Vector,logical(length(Vector)))
    • 感谢@nicola,我不习惯 vapply 但似乎我应该这样做 ;-)
    • 看起来很棒:)。不幸的是,我在 Vector 中有一些不可预测的拼写错误(例如 Pris 而不是 Paris),并且在使用 apply 方法时,它会挤出在 City 向量中找不到匹配项的行。是否可以将具有匹配的向量(您的方法是完美的)和不匹配的向量汇总到一个向量中(以供进一步分析)。附言感谢 vapply 的提示
    • 嗨@jernac,我真的不明白你的意思,我用Vector &lt;- c(Vector, "I like Mdrid") 尝试了一个案例,结果得到了一个包含4个元素的列表,其中一个名为“我喜欢Mdrid”并具有价值character(0)。您可以进一步取消列出此结果,但在此之前,您需要将 character(0) 替换为 NA (unlist(lapply(apply(check_vec, 1, function (x) colnames(check_vec)[which(x)]), function(x) {if (!length(x)) x &lt;- NA else x})))
    • 太棒了,它现在可以工作了。在替换字符(0)之前,我太快了,无法列出结果。感谢您的帮助:)
    【解决方案2】:

    这是一个使用文本分析包的方法,quanteda。它允许您为城市名称设置一组模式匹配,例如,如果您有不同的城市拼写(例如“Rome”和“Roma”)但想将它们算作一个城市,这很有用。下面的匹配使用简化的“glob”格式,但您也可以使用正则表达式匹配。

    require(quanteda)
    
    # only required if you have compound word city names
    compoundCities <- dictionary(list(NY = "New York"))
    VectorPhrased <- phrasetotoken(Vector, compoundCities)
    
    # uses the "glob" format for Pattern Matching
    citiesDict <- dictionary(list(London = c("London", "Londres"), Paris = "Paris", 
                                  Rome = "Rom?", NewYork = "New_York"))
    
    dfm(VectorPhrased, dictionary = citiesDict, verbose = FALSE)
    # Document-feature matrix of: 3 documents, 4 features.
    # 3 x 4 sparse Matrix of class "dfmSparse"
    #        features
    # docs    London Paris Rome NewYork
    #   text1      0     1    0       0
    #   text2      0     0    1       0
    #   text3      0     0    0       1
    

    【讨论】:

    • 这对我不起作用。为了避免复合名称,我使用 tolower 并删除所有空格来获得干净整洁的字符串(例如 thelifeinparisis)。然后我用小写字母的城市组成字典。 text1的真实值能显示出来吗?
    • 我不确定你的意思,因为它不是你的例子的一部分。但是,如果您更改valuetype = "regex",那么即使在“thelifeinparis”之类的字符串中,您也可以找到“paris”的匹配项。但是,如果您扩展示例,我可以直接解决它。
    • 太好了,它可以工作(顺便说一句,不错的包)。没有明确说明示例背后的整个过程是我的错。我看到该值类型采用 3 个参数(glob、正则表达式和固定)。我不明白 glob 格式(“glob”风格的通配符),它与正则表达式有什么不同(两者都用于模式匹配)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 2022-08-03
    相关资源
    最近更新 更多