【问题标题】:Replace values in data frame based on other data frame in R根据R中的其他数据框替换数据框中的值
【发布时间】:2013-02-25 15:04:35
【问题描述】:

在下面的示例中,userids 是我的参考数据框,userdata 是应该进行替换的数据框。

> userids <- data.frame(USER=c('Ann','Jim','Lee','Bob'),ID=c(1,2,3,4))
> userids
  USER ID
1  Ann  1
2  Jim  2
3  Lee  3
4  Bob  4

> userdata <- data.frame(INFO=c('foo','bar','foo','bar'), ID=c('Bob','Jim','Ann','Lee'),AGE=c('43','33','53','26'), FRIENDID=c('Ann',NA,'Lee','Jim'))
> userdata
  INFO  ID AGE FRIENDID
1  foo Bob  43      Ann
2  bar Jim  33       NA
3  foo Ann  53      Lee
4  bar Lee  26      Jim

如何将userdata中的ID和FRIENDID替换为userids中USER对应的ID?

想要的输出:

  INFO  ID AGE FRIENDID
1  foo   4  43        1
2  bar   2  33       NA
3  foo   1  53        3
4  bar   3  26        2

【问题讨论】:

  • “正确”是什么意思?是否要将userids$USERuserdata$ID 匹配?
  • 我猜correct应该是corresponding
  • @Robert,获得所需的输出会有所帮助(下次避免这些混淆)。

标签: r dataframe


【解决方案1】:

使用match:

userdata$ID <- userids$ID[match(userdata$ID, userids$USER)]
userdata$FRIENDID <- userids$ID[match(userdata$FRIENDID, userids$USER)]

【讨论】:

    【解决方案2】:

    这是一种可能:

    library(qdap)
    userdata$FRIENDID <- lookup(userdata$FRIENDID, userids)
    userdata$ID <- lookup(userdata$ID, userids)
    

    或赢得单线奖:

    userdata[, c(2, 4)] <- lapply(userdata[, c(2, 4)], lookup, key.match=userids)
    

    【讨论】:

    • qdap 看起来不错,但我的存储库中没有看到它。
    • 不知道为什么。也许是因为它是一个较新的版本。尝试install.packages("qdap") 或者您可以使用:library(devtools) install_github("qdap", "trinker") 用于开发人员。版本。
    • 失败。 ERROR: dependency 'openNLP' is not available for package 'qdap'
    • 您使用的是什么操作系统?如果是mac,你必须从源代码编译。详情请见:trinker.github.com/qdap_install/installation
    • @agstudy。错过了。你是对的。我进行了编辑以反映这一点。
    【解决方案3】:

    这里尝试使用sqldf 将结果作为不同列上的多重连接。

      library(sqldf)
      sqldf('SELECT d.INFO,d.AGE,i1.ID ,i2.ID FRIENDID
           FROM 
           userdata d
           INNER JOIN 
           userids i1 ON (i1.USER=d.FRIENDID)
           INNER JOIN
            userids i2 ON (i2.USER=d.ID)')
    
     INFO AGE ID FRIENDID
    1  foo  43  1        4
    2  foo  53  3        1
    3  bar  26  2        3
    

    但这会删除 NA 行!也许有人可以建议我如何处理 NA!

    编辑

    感谢 G. Grothendieck 的评论,将 INNER 替换为 LEFT,我们得到了结果。

     sqldf('SELECT d.INFO,d.AGE,i1.ID ,i2.ID FRIENDID
            FROM 
            userdata d
            LEFT JOIN 
            userids i1 ON (i1.USER=d.FRIENDID)
            LEFT JOIN
             userids i2 ON (i2.USER=d.ID)')
    INFO AGE ID FRIENDID
    1  foo  43  1        4
    2  bar  33 NA        2
    3  foo  53  3        1
    4  bar  26  2        3
    

    【讨论】:

    • 关于您的问题,将 INNER 的两个实例替换为 LEFT
    【解决方案4】:

    这是一个可能的解决方案,它也适用于每个 ID 的多条记录的数据集,但我们需要先将 ID 和 FRIENDID 变量强制转换为字符:

    > userdata$ID <- sapply(userdata$ID, function(x){gsub(x, userids[userids$USER==x, 2], x)})
    > userdata$FRIENDID <- sapply(userdata$FRIENDID, function(x){gsub(x, userids[userids$USER==x, 2], x)})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      相关资源
      最近更新 更多