【问题标题】:Transforming character strings in R在 R 中转换字符串
【发布时间】:2010-08-28 08:28:35
【问题描述】:

我必须合并到 R 中的数据框。这两个数据框共享一个公共 id 变量,即主题的名称。但是,一个数据框中的名称部分大写,而在另一个数据框中则小写。此外,名称以相反的顺序出现。以下是来自数据帧的示例:

DataFrame1$Name:
"Van Brempt Kathleen"
"Gräßle Ingeborg"
"Gauzès Jean-Paul"
"Winkler Iuliu" 

DataFrame2$Name:
"Kathleen VAN BREMPT" 
"Ingeborg GRÄSSLE"
"Jean-Paul GAUZÈS"
"Iuliu WINKLER"

在 R 中有没有办法让这两个变量可用作合并数据帧的标识符?

最好的,托马斯

【问题讨论】:

    标签: r data-structures statistics


    【解决方案1】:

    您可以使用 gsub 来转换周围的名称:

    > names
    [1] "Kathleen VAN BREMPT" "jean-paul GAULTIER" 
    > gsub("([^\\s]*)\\s(.*)","\\2 \\1",names,perl=TRUE)
    [1] "VAN BREMPT Kathleen" "GAULTIER jean-paul" 
    > 
    

    首先匹配第一个空格之前的任何内容,然后匹配之后的任何内容,然后切换它们。然后根据需要添加 tolower() 或 toupper(),并使用 match() 加入数据框。

    不过,祝 Grassle 与 Graßle 相匹配。很多其他的东西也可能会咬你,比如两个名字用空格隔开的人,或者列出一个标题的人!

    巴里

    【讨论】:

    • 谢谢巴里,你说得对,这不是没有问题的,我很可能不得不手工做一些事情,但希望这会减少一点工作量:)
    【解决方案2】:

    这是一个完整的解决方案,它结合了目前提供的两种部分方法(并克服了 Spacedman 表达的关于“将 Grassle 与 Graßle 匹配”的担忧):

    DataFrame2$revname <- gsub("([^\\s]*)\\s(.*)","\\2 \\1",DataFrame2$Name,perl=TRUE)
    DataFrame2$agnum <-sapply(tolower(DataFrame2$revname), agrep, tolower(DataFrame1$Name) )
    DataFrame1$num <-1:nrow(DataFrame1)
    merge(DataFrame1, DataFrame2, by.x="num", by.y="agnum")
    

    输出:

      num              Name.x              Name.y             revname
    
    1   1 Van Brempt Kathleen Kathleen VAN BREMPT VAN BREMPT Kathleen
    2   2     Gräßle Ingeborg    Ingeborg GRÄSSLE    GRÄSSLE Ingeborg
    3   3    Gauzès Jean-Paul    Jean-Paul GAUZÈS    GAUZÈS Jean-Paul
    4   4       Winkler Iuliu       Iuliu WINKLER       WINKLER Iuliu
    

    如果 DatFrame1 的行名仍然按顺序编号(默认情况下),则不需要第三步。合并语句将是:

    merge(DataFrame1, DataFrame2, by.x="row.names", by.y="agnum")
    

    -- 大卫。

    【讨论】:

      【解决方案3】:

      您能否为每个数据框添加一个额外的列/变量,它是原始名称的小写版本:

      DataFrame1$NameLower <- tolower(DataFrame1$Name)
      DataFrame2$NameLower <- tolower(DataFrame2$Name)
      

      然后对此进行合并:

      MergedDataFrame <- merge(DataFrame1, DataFrame2, by="NameLower")
      

      【讨论】:

      • 抱歉 - 我也错过了有关反向排序的内容,您必须编写一个自定义函数将所有大写文本移动到名称的开头,并将其小写。
      • 谢谢 Joel,你知道如何编写这样的函数吗?
      【解决方案4】:

      除了使用 gsub 重新排列名称的答案之外,您可能还想查看 agrep 函数,它会查找近似匹配项。您可以将其与 sapply 一起使用来查找从一个数据帧到另一个数据帧的匹配行,例如:

      > sapply( c('newyork', 'NEWJersey', 'Vormont'), agrep, x=state.name, ignore.case=TRUE )
        newyork NEWJersey   Vormont 
             32        30        45 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-29
        • 2021-03-14
        • 1970-01-01
        • 2018-05-12
        • 2022-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多