按组标识值变化(类别)。 R

时间:2019-03-13 19:45:21

标签: r group-by dplyr lag

下面您可以看到我的数据集的一个样本。

Fac Date        Type        Change  StartDT     EndDT
AAA 1/1/2019    General     0   1/1/2019    1/2/2019
AAA 1/2/2019    General     0   1/1/2019    1/2/2019
AAA 1/3/2019    Special     1   1/3/2019    1/4/2019
AAA 1/4/2019    Special     1   1/3/2019    1/4/2019
AAA 1/5/2019    Intensive   2   1/5/2019    1/5/2019
BBB 1/1/2019    General     0   1/1/2019    1/4/2019
BBB 1/2/2019    General     0   1/1/2019    1/4/2019
BBB 1/3/2019    General     0   1/1/2019    1/4/2019
BBB 1/4/2019    General     0   1/1/2019    1/4/2019
BBB 1/5/2019    Reserve     1   1/5/2019    1/6/2019
BBB 1/6/2019    Reserve     1   1/5/2019    1/6/2019

我想创建一个变量来跟踪我的Type变量(更改)中的更改。我以前在Stata中工作,执行此操作的逻辑是首先跟踪每个面板/组的值与先前记录(0/1)相比是否发生变化,然后对该值求和。

bysort Facility (Date): gen byte era = sum(Type != Type[_n-1] & _n > 1) 

如何在R中做到这一点?同样,在创建更改变量之后,我将需要为每个Fac和Change(“时代”)生成开始和结束(最小,最大)日期。

我将不胜感激!提前致谢! 马文

3 个答案:

答案 0 :(得分:0)

这是使用dplyr的一种解决方案:

dat =
  tibble(
    fac = c(rep("A", 10), rep("B", 10)),
    type = sample(1:3, 20, replace = TRUE)
  )

dat %>% 
  group_by(fac) %>% 
  mutate(
    change = case_when(
      type != lag(type) ~ TRUE,
      TRUE ~ FALSE
    ),
    n_change = cumsum(change)
  )

对于您的代码,您可以添加:

group_by(Fac, n_change) %>%
mutate(
  min_start_date = min(StartDT),
  max_start_date = max(EndDT)
)

答案 1 :(得分:0)

考虑使用sapply遍历行号序列以检查当前行和上一行的 Type 值。并使用ave Fac 组的总数进行内联聚合:

dat <- within(dat, {
  # CONVERT DATES
  Date <- with(dat, as.Date(Date, format="%m/%d/%Y"))
  StartDT <- with(dat, as.Date(StartDT, format="%m/%d/%Y"))
  EndDT <- with(dat, as.Date(StartDT, format="%m/%d/%Y"))

  # CALCULATE TYPE CHANGES
  type_delta <- c(NA, sapply(2:nrow(dat), function(i) 
                               ifelse(dat$Type[i] != dat$Type[i-1], 1, 0)
                             )
                 )
  era <- ave(type_delta, Fac, FUN=function(x) sum(x, na.rm=TRUE))
})

dat    
#    Fac       Date      Type Change    StartDT      EndDT era type_delta
# 1  AAA 2019-01-01   General      0 2019-01-01 2019-01-01   2         NA
# 2  AAA 2019-01-02   General      0 2019-01-01 2019-01-01   2          0
# 3  AAA 2019-01-03   Special      1 2019-01-03 2019-01-03   2          1
# 4  AAA 2019-01-04   Special      1 2019-01-03 2019-01-03   2          0
# 5  AAA 2019-01-05 Intensive      2 2019-01-05 2019-01-05   2          1
# 6  BBB 2019-01-01   General      0 2019-01-01 2019-01-01   2          1
# 7  BBB 2019-01-02   General      0 2019-01-01 2019-01-01   2          0
# 8  BBB 2019-01-03   General      0 2019-01-01 2019-01-01   2          0
# 9  BBB 2019-01-04   General      0 2019-01-01 2019-01-01   2          0
# 10 BBB 2019-01-05   Reserve      1 2019-01-05 2019-01-05   2          1
# 11 BBB 2019-01-06   Reserve      1 2019-01-05 2019-01-05   2          0

答案 2 :(得分:0)

非常感谢@Parfait和@ user2363777提供的所有帮助!这真太了不起了。我使用了user2363777解决方案,因为我对dplyr更加熟悉。对于最后的代码块,我只是在最后添加了ungroup()函数。然后,我只记录每个设施和时代的记录。

Fac Era Type            StartDT     EndDT
AAA 0   General         1/1/2019    1/2/2019
AAA 1   Special         1/3/2019    1/4/2019
AAA 2   Intensive       1/5/2019    1/5/2019
BBB 0   General         1/1/2019    1/4/2019
BBB 1   Reserve         1/5/2019    1/6/2019

我的最终目标是生成描述设施类型随时间变化(类别变量随时间变化)的图形。我将研究如何绘制图形。我可能很快会发布一些相关信息。谢谢!!