Хитрое слияние с датами в r - расширение строк от одного df, чтобы соответствовать другому - PullRequest
0 голосов
/ 06 января 2019

Итак, у меня есть два кадра данных, в аккуратном формате:

  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))

Обратите внимание, что, хотя у меня нет информации для бюджетного счета с первой даты, когда на счету salay-счета есть строка, я использую информацию с первого раза, когда равен a строка из бюджетного счета.

здесь я изменил имена столбцов для переменной баланса, чтобы одна строка могла иметь баланс для обоих, но это не является существенной частью решения, только то, что результат может быть вычислен следующим образом:

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

Я пытался использовать скрещивание () согласно этому ответу, Копирование строки из одного df в каждый ряд в другом , но, насколько я могу судить, в этом случае бесполезно.

Спасибо.

PS Я предпочитаю нереализованное решение - я большой поклонник data.table самостоятельно - но нищие не могут быть выбором :)

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Смесь основания 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
0 голосов
/ 06 января 2019

Я вижу, что вы предпочитаете 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

Во-первых, переименовывает столбец «balance» в df1 в «balance.salary» и «balance.budget» в df2. Во-вторых, он объединяет две DFS на «дату». Наконец, он заполняет пропущенные значения последним значением, отличным от NA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...