优雅地联接表(即使不存在表)

时间:2019-04-26 20:00:58

标签: r join dplyr

我正在循环工作,并在每次迭代中生成df。在迭代过程中,我将结果合并到一个大表中。以下代码按预期工作,但看起来过于复杂。有没有一种方法可以简化此过程,所以我不必使用if / else块?

if(exists("ModelOutput.Full")){
  ModelOutput.Full <- ModelOutput.Full%>%
    distinct()%>%
    left_join(ModelOutput, by = "ID")
} else {
  ModelOutput.Full <- ModelOutput
}

我希望只使用else代码并在第一次迭代中创建ModelOutput.Full,但这不会发生。

此外,请随时提出我没有在询问的其他优化。我确定它们存在。

编辑2:感谢DSGym的投入,尽管我对他们的回答做了些微修改,但由于我在最初的问题中没有提供可重现的代码,因此我已经完成了这项工作。这是对我有用的说明:

regions <- c(1:7)
drivers <- c(1:5)
ModelOutput <- list()
ModelOutput.Regional <- list()
ID <- c(1:6961896)%>%
  as.vector()%>%
  as.data.frame()%>%
  rename("ID"=".")
modelOutput <- list()
modelOutput.regional <- list()
for (region in regions) {
  for (driver in drivers)
    vals <- sample(0:10, 6961896, replace = TRUE)/10
    outName <- paste("driver",driver,sep="")
    vals <- vals%>%
      as.vector()%>%
      as.data.frame()%>%
      rename(!!outName := ".")%>%
      bind_cols(ID)
    ModelOutput[[driver]] <- vals
  }
  ModelOutput.Regional[[region]] <- as.data.frame(Reduce(function(x, y) merge(x, y, by = "ID", all.x = TRUE), ModelOutput))
}
ModelOutput.Full <- Reduce(function(x, y) bind_rows(x, y), ModelOutput.Regional)

这会生成我想要的巨型数据框输出,其中包含所有区域数据以及每个“驾驶员”的得分,这些列在带有标签的列中如下所示:

ID  driver1 driver2 driver3 driver4 driver5
1     0.1     0.2     0.4     0.6     0.4
2     0.4     0.6     0.5     0.7     0.7
3     0.3     0.7     0.5     0.2     0.3

2 个答案:

答案 0 :(得分:0)

正如MrFlick在上述评论中所述。最后更容易组合数据帧。您可以执行以下操作。

由于我不知道您的循环结构是什么样子,因此我假设您可以生成一个称为dfs的数据帧矢量

# method 1
ModelOutput.Full = dplyr::bind_rows(dfs)

# method 2
ModelOutput.Full = do.call("rbind", dfs)

答案 1 :(得分:0)

如果没有可复制的示例,不是100%不确定如何做,但是我认为这应该有所帮助:

  1. 将所有数据框存储在列表中

storelist <- list() ## Store all your df´s

使用循环并像这样存储它

for(i in 1:length(dfs) {
   storelist[[i]] <- dfs[[i]]
}

使用此功能按ID连接所有数据框

Reduce(function(x) merge(x, by='ID', all.x=TRUE), storelist)