使用合并创建空行

时间:2018-02-08 11:26:20

标签: r dplyr

我正在使用相同的输入参数运行多个模拟。有些模拟比其他模拟更早完成,我需要扩展较短模拟的结果,以便我可以分析包含所有运行的数据。这意味着用重复的最终值填充'短'运行,直到它们与具有相同输入参数的'long'运行的长度相同。

我想要一个dplyr解决方案,因为真正的数据集是庞大的,dplyr有快速连接。

这是我的尝试。

library(dplyr)
sims <- data.frame("run" = c(1, 1, 1, 2, 2, 3, 3),
                   "type" = c("A", "A", "A", "A", "A", "B", "B"),
                   "step" = c(0, 1, 2, 0, 1, 0, 1),
                   "value" = seq(1:7))
allSteps <- data.frame("type" = c("A", "A", "A", "B", "B"),
                       "step" = c(0, 1, 2, 0, 1))

merged <- full_join(sims, allSteps,
                    by = c("type", "step"))

这得到输出:

 run type step value
   1    A    0     1
   1    A    1     2
   1    A    2     3
   2    A    0     4
   2    A    1     5
   3    B    0     6
   3    B    1     7

但我实际上想要以下内容,因为第2版是A类型,因此应该扩展到与第1行相同的长度(也是类型A):

 run type step value
   1    A    0     1
   1    A    1     2
   1    A    2     3
   2    A    0     4
   2    A    1     5
   2    A    2     NA   # extra line here
   3    B    0     6
   3    B    1     7

然后我将使用填充来达到我想要的结果:

 run type step value
   1    A    0     1
   1    A    1     2
   1    A    2     3
   2    A    0     4
   2    A    1     5
   2    A    2     5    # filled replacement of NA
   3    B    0     6
   3    B    1     7

我确信这是一些问题的副本,但我使用的各种搜索字词都无法表现出来。

3 个答案:

答案 0 :(得分:2)

如果至少有一个运行包含每种类型的完整序列,那么我们真的不需要data.frame allSteps。相反,我们可以将tidyr::expand()与自我加入结合使用:

library(tidyr)
sims %>% group_by(type) %>%
  expand(run, step) %>%
  full_join(sims, by = c("type", "step", "run")) %>%
  select(2,1,3,4)
#    run   type  step value
#  <dbl> <fctr> <dbl> <int>
#1     1      A     0     1
#2     1      A     1     2
#3     1      A     2     3
#4     2      A     0     4
#5     2      A     1     5
#6     2      A     2    NA
#7     3      B     0     6
#8     3      B     1     7

答案 1 :(得分:1)

使用 tidyr :: complete 来获取缺失的组合,然后使用 fill 来填充具有最后非NA值的NAs:

my_package.py

答案 2 :(得分:0)

我们可以逐行拆分数据框,并在right_join上为每个数据框执行allSteps,以获得所需的所有组合。然后我们加入并填补。

它比当前的解决方案更为通用,因为allSteps中的步骤可能不在simssims子集中工作。

library(tidyverse)

sims %>%
  split(.$run) %>%
  map_dfr(right_join,allSteps,.id = "id") %>%
  group_by(type,id) %>%
  fill(run,value,.direction="down") %>%
  ungroup %>%
  filter(!is.na(run)) %>%
  select(-id)

# # A tibble: 8 x 4
#     run   type  step value
#   <dbl> <fctr> <dbl> <int>
# 1     1      A     0     1
# 2     1      A     1     2
# 3     1      A     2     3
# 4     2      A     0     4
# 5     2      A     1     5
# 6     2      A     2     5
# 7     3      B     0     6
# 8     3      B     1     7