在R

时间:2017-01-30 22:57:56

标签: r date dplyr data-manipulation

我有以下数据框:

df <- structure(list(Jmbg = c("0402977385033", "0402977385033", "0402977385033", 
"0402977385033", "0402977385033", "0402977385033", "0402977385033", 
"0402977385033", "0402977385033", "0402977385033", "0402977385033", 
"0402977385033", "0402977385033", "0402977385033", "0402977385033", 
"0402977385033", "0402977385033", "0402977385033", "2607954335134", 
"2607954335134", "2607954335134", "2607954335134", "2607954335134"
), DatumOd = structure(c(11260, 11457, 11503, 11603, 11696, 11826, 
11875, 12013, 12043, 12133, 12225, 12225, 12317, 12408, 12499, 
13878, 14425, 16203, 10915, 11687, 12372, 13878, 15217), class = "Date"), 
    DatumDo = structure(c(11455, 11502, 11520, 11695, 11800, 
    11941, 12012, 12042, 12132, 12224, 12225, 12316, 12407, 12498, 
    13877, NA, NA, NA, 11686, 12371, 13877, NA, NA), class = "Date")), row.names = c(NA, 
-23L), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), vars = list(
    Jmbg), drop = TRUE, indices = list(0:17, 18:22), group_sizes = c(18L, 
5L), biggest_group_size = 18L, .Names = c("Jmbg", "DatumOd", 
"DatumDo"), labels = structure(list(Jmbg = c("0402977385033", 
"2607954335134")), row.names = c(NA, -2L), class = "data.frame", vars = list(
    Jmbg), drop = TRUE, indices = list(c(0L, 2L, 3L, 4L, 5L, 
6L, 8L, 9L, 10L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 22L), 
    c(1L, 7L, 11L, 20L, 21L)), group_sizes = c(18L, 5L), biggest_group_size = 18L, .Names = "Jmbg"))

第一列是id。第二列是某个事件开始的日期,第三列是事件结束的日期。如您所见,列Datumdo中存在一些缺失值。我想以下列方式填充这些缺失的值:如果缺少值,但DatumOd日期是id的最后一个,则它应该保持NA。如果缺少日期并且不是最后DatumOd个日期,那么DatumOd列的下一个日期应减去一天。

我尝试了dplyr

df_2 <- df %>%
  dplyr::group_by(Jmbg) %>%
  dplyr::mutate(novi_date = ifelse(is.na(DatumDo) & DatumOd != max(DatumOd), "test", DatumDo))

但是代替测试,该{id}的DatumOd列应该有下一个日期。例如,对于最后一次&#34;测试&#34;,应该有一个日期2011-08-30。 当然,您可以使用任何其他包(data.table ...)

1 个答案:

答案 0 :(得分:1)

以下是使用data.table的答案。它使用shift函数查找每行的前导日期(减去一天),并按ID将其分配给新列dayBeforeNext。从那里,ifelse根据DatumDo中是否已有日期,将新日期分配给另一个新变量。

我需要在分配日期之前将日期转换为字符,然后再更新,因为似乎有一个错误在ifelse语句中通过引用data.table分配日期类型。

setDT(df)
df[, dayBeforeNext := as.character(shift(DatumOd, type='lead')-1), by=Jmbg]
df[, DatumDo := as.character(DatumDo)]

df[, new := ifelse(is.na(DatumDo), dayBeforeNext, DatumDo)]

df[, new := as.Date(new)]

您的新`data.table将有额外的列,以便您可以根据需要重新分配/删除它们。