【问题标题】:Partial merge in RR中的部分合并
【发布时间】:2023-03-22 21:17:01
【问题描述】:

在我像 Two by two matching between dataframes in r 那样以 -7 结束之前,让我说我已经阅读了以下页面:

其实最后一个真的和我想要的很像,但又不一样,因为我的栏目不一样

我有两个数据框,比如说:

> d <- data.frame(year=c(2004,2004,2006),month = c(1,5,3), height = c(1000,2000,3000) )
> d
  year month height
1 2004     1   1000
2 2004     5   2000
3 2006     3   3000

> e <- data.frame(year=c(2004),month=c(5), height = c(9999))
> e
  year month height
1 2004     5   9999

显然真实数据比这个长。

我想将 e 中的值合并到 d 中

尝试原始合并:

> merge(d,e)
[1] year   month  height
<0 rows> (or 0-length row.names)

好的。所以加上“by”:

> merge(d,e,by=c("year","month"))
  year month height.x height.y
1 2004     5     2000     9999

好的,它做了一个内连接,并去掉了 d 中的所有原始数据。所以尝试左外连接:

> merge(d,e,by=c("year","month"),all.x = T)
  year month height.x height.y
1 2004     1     1000       NA
2 2004     5     2000     9999
3 2006     3     3000       NA

它做了一个连接,根据外连接定义它是正确的,但它没有做我想要的,即从 e 中的值更新 d 中的值。我真正想要的更像是一个 sql 更新:

for (year,month,height) in e:
    update d set d.height=e.height where d.year = e.year and d.month = e.month

即我想要的结果是:

> magic(d,e)
  year month height
1 2004     1   1000
2 2004     5   9999
3 2006     3   3000

当然,我可以只写一堆for 循环,但我希望有一些矢量化的方式来做到这一点?

编辑:我的示例只有一个键列,但我真正的问题有两个。更新了示例以反映这一点。

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以使用data.table

    编辑注意 e 和 d 都有一个按月和年定义的键

    library(data.table)
    DD <- as.data.table(d)
    DE <- as.data.table(e)
    
    setkey(DD,  year, month)
    setkey(DE,  year, month)
    
    DD[DE, height := i.height]
    

    请注意,我在高度前加上了i.,以确保它从i 组件中读取高度值。

    如果您阅读 data.table 小插图的介绍,您将很快了解 rownames 和 data.table 键之间的关系!

    【讨论】:

      【解决方案2】:

      其实下面的方法更直接:

      rownames( d ) <- d$id
      d[ e$id, ]$height <- e$height
      

      更新:由于您的键实际上是“年-月”,您可能最好使用数据表,但如果您不愿意使用它,您可以这样做:

      rownames( d ) <- paste( d$year, d$month )
      d[ paste( e$year, e$month ), ]$height <- e$height
      

      【讨论】:

      • 不幸的是,我有两个键,尽管我最初的问题通过给出只有一个的示例数据隐含地表明有一个。我已经用两个键的示例更新了问题。
      • 在这种情况下,我建议按照@mnel 的建议使用data.table。虽然您可以使用paste( year, month ) 作为您的密钥(好吧,实际上您只有一个密钥:“年-月”)。
      • 我最终采用了这种方法,因为虽然在我看来有点“老套”,但它的学习曲线为零。
      • 肯定是“旧式”。每当我必须使用data.table 时,我都必须查找习语,而rownames 和data.frames 已经在我的血液中。
      猜你喜欢
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多