合并基于年份的data.frames并填写缺失值

时间:2017-04-20 14:00:19

标签: r dataframe

我想要合并两个data.frames。第一个是:

a <- data.frame(matrix(ncol = 3, nrow = 5))
colnames(a) <- c('a', 'y', 'Z')
a$Z <- c(1, 3, 4, 5, 2)
a$a <- c(2005, 2006, 2007, 2008, 2009)
a$y <- c('abc', 'def', 'ijk', 'xyz', 'thanks')

第二个:

Date          y      Z
2005-01-01   abc     1
2005-01-02   abc     1 
2005-01-03   abc     1
{cont}
2009-12-31   thanks  2

我希望合并后的那一年匹配年份,然后填写当年每一天的其余值。

{{1}}

4 个答案:

答案 0 :(得分:5)

到目前为止,已经发布了三种不同的方法:

Frank在聊天中提出了第四种叫做 update join 的方法:

class CarViewController: UIViewController {
  @IBOutlet modelLabel: UILabel!
  @IBOutlet makeLabel: UILabel!
  @IBOutlet horsepowerLabel: UILabel!
  @IBOutlet titleLabel: UILabel!
  @IBOutlet image: UIImageView!

  var viewModel: CarViewModel!

  override func viewDidLoad() {
    self.modelLabel.reactive.text <~ self.viewModel.modelTextSignal
    self.makeLabel.reactive.text <~ self.viewModel.makeTextSignal
    self.horsepowerLabel.reactive.text <~ self.viewModel.horsepowerTextSignal
    self.titleLabel.reactive.text <~ self.viewModel.titleTextSignal
    self.viewModel.photoURLSignal.startWithValues { [weak self] url in
      self?.setImageFromUrl(url)
    }
  }

  func displayNewCar() {
    self.viewModel.car.value = aRandomCar()
  }

  private func setImageFromUrl(url: URL?) {
    //download url and display in UIImageView
  }
  private func aRandomCar() -> Car {
    //return a Car object
  }
}

这是四个中最快,最简洁的。

基准测试结果:

要确定哪种方法在速度方面最有效,我使用library(data.table) setDT(sample)[, yr := year(Date)][setDT(a), on = .(yr = a), `:=`(y = i.y, Z = i.Z)] 包设置了基准。

microbenchmark

Unit: microseconds expr min lq mean median uq max neval create_data 248.827 291.116 316.240 302.0655 323.588 665.298 100 match 4488.685 4545.701 4752.226 4649.5355 4810.763 6881.418 100 dplyr 6086.609 6275.588 6513.997 6385.2760 6625.229 8535.979 100 merge 2871.883 2942.490 3183.712 3004.6025 3168.096 5616.898 100 update_join 1484.272 1545.063 1710.651 1659.8480 1733.476 3434.102 100 被修改时,必须在每次基准运行之前重新创建它。这是由一个包含在基准测试中的函数完成的(创建数据)。 创建数据的时间需要从其他时间中减去。

因此,即使对于大约1800行的小数据集,更新连接是最快的,几乎是第二个 merge 的两倍,其次是匹配 dplyr 是最后一次,比更新连接慢了4倍(减去创建数据的时间)。

基准代码

sample

答案 1 :(得分:2)

您可以使用match

matched<-match(format(sample$Date,"%Y"),a$a)
sample$y<-a$y[matched]
sample$Z<-a$Z[matched]

答案 2 :(得分:0)

如果y中的Zsample始终为零,那么您在那里不需要它们,所以您需要做的就是加入这样的年份:

 library(dplyr)
 sample %>% mutate(a = format(Date, "%Y") %>% as.numeric) %>% 
   inner_join(a %>% select(a)) 

答案 3 :(得分:0)

有没有什么可以反对在你的新df中添加一年的专栏?如果没有,你可以生成一个&#39;样本&#39;并使用合并功能

require(lubridate) #to make generating the year easy 
sample2<-data.frame(Date=datess)
sample2$a<-year(sample2$Date)
df<-merge(sample2,a,by="a")

这将导致类似这样的事情:

head(df)
     a       Date   y Z
1 2005 2005-01-01 abc 1
2 2005 2005-01-02 abc 1
3 2005 2005-01-03 abc 1
4 2005 2005-01-04 abc 1
5 2005 2005-01-05 abc 1
6 2005 2005-01-06 abc 1

如果遇到麻烦,您可以再次删除年份列。