我正在使用相同的输入参数运行多个模拟。有些模拟比其他模拟更早完成,我需要扩展较短模拟的结果,以便我可以分析包含所有运行的数据。这意味着用重复的最终值填充'短'运行,直到它们与具有相同输入参数的'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
我确信这是一些问题的副本,但我使用的各种搜索字词都无法表现出来。
答案 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
中的步骤可能不在sims
或sims
子集中工作。
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