Tricky与R中的日期合并-从一个df扩展行以匹配另一个

时间:2019-01-06 14:33:34

标签: r date merge

所以我有两个整齐的数据框:

  df1 <- data.frame(date=as.Date(paste0('2018-12-',c(11,15,18,22,25,29))), balance=c(-500,-250,0,250,-300,500), account='salary')
  df2 <- data.frame(date=as.Date(paste0('2018-12-',c(16,22,27))), balance=c(1000, 700, 250), account='budget')

现在,这是我的预算帐户和日常帐户的余额。这两个数据框中的“余额”列的总和即为我在任何给定的一天所拥有的金额。

但是,由于如果进行更改余额的传输,则数据框中仅存在一行,因此使计算复杂化。合并必须完成,因此对于每个数据框中的每一行,在另一个数据框中的每一行都必须与该日该帐户的余额相对应。因此,玩具示例中的结果将是这样:

  df.result <- data.frame(date=as.Date(paste0('2018-12-',c(11,15,16,18,22,25,27,29))), balance.salary=c(-500,-250,-250,0,250,-300,-300,500), balance.budget=c(1000,1000,1000,1000,700,700,250,250))

请注意,即使我从第一天开始就没有关于预算帐户的信息,但我正在使用的第一时间是 预算帐户中的一行。

在这里,我更改了balance-variable的列名称,以便一行可以同时具有两个的balance,但这不是解决方案的必要组成部分,只是可以这样计算结果:

  df.result$balance.total <- df.result$balance.salary + df.result$balance.budget

我已尝试按照此答案Copying row from one df into everyone row in another使用crossing(),但据我所知,在这种情况下没有用。

谢谢。

PS我更喜欢非tidyverse解决方案-我本人是data.table的忠实拥护者-但乞g不能成为选择者:)

2 个答案:

答案 0 :(得分:4)

我发现您更喜欢data.table,但是也许tidyverse解决方案也将很有用:

df1 %>%
 rename(balance.salary = balance) %>%
 select(-account) %>%
 full_join(df2 %>%
            rename(balance.budget = balance) %>%
            select(-account), by = c("date" = "date")) %>%
 arrange(date) %>%
 fill(balance.salary, .direction = "down") %>%
 fill(balance.budget, .direction = "down") %>%
 fill(balance.budget, .direction = "up")

        date balance.salary balance.budget
1 2018-12-11           -500           1000
2 2018-12-15           -250           1000
3 2018-12-16           -250           1000
4 2018-12-18              0           1000
5 2018-12-22            250            700
6 2018-12-25           -300            700
7 2018-12-27           -300            250
8 2018-12-29            500            250

首先,将df1中的“ balance”列重命名为“ balance.salary”,并将其重命名为df2中的“ balance.budget”。其次,它将“日期”上的两个df合并。最后,它用最后一个非NA值填充缺失值。

答案 1 :(得分:1)

R和zoo溶液的混合物。我们首先通过merge对数据帧进行date处理,然后使用na.locf填充缺失值。

library(zoo)
na.locf(na.locf(merge(df1[-3], df2[-3], all = TRUE, by = "date")), fromLast = TRUE)


#        date balance.x balance.y
#1 2018-12-11      -500      1000
#2 2018-12-15      -250      1000
#3 2018-12-16      -250      1000
#4 2018-12-18         0      1000
#5 2018-12-22       250       700
#6 2018-12-25      -300       700
#7 2018-12-27      -300       250
#8 2018-12-29       500       250