首页 > 解决方案 > 检查一个 ID 的分类器/属性是否从一个月到下个月发生变化,如果发生变化,则创建一个变化列表

问题描述

我有一个带有“DATE”列、“ID”列和“CLASSIFIER”列的data.frame,如下所示:

set.seed(11)
Data <- data.frame(
        DATE = sample(seq(as.Date("2010-02-01"), length=12, by="1 month") - 1,50,replace = TRUE),
        ID = sample(1:9,50,replace = TRUE),
        CLASSIFIER = sample(c("yes", "no"), 50, replace = TRUE)
      )

输出如下所示:

        DATE ID CLASSIFIER
1 2010-03-31  3        yes
2 2010-04-30  3         no
3 2010-04-30  4         no
4 2010-06-30  4        yes
5 2010-09-30  2         no
6 2010-11-30  5         no

我现在想获取分类器从一个日期更改为下一个日期的那些 ID 的列表。换句话说,我想要一个从一个月到下个月从"yes"to"no""no"to变化的所有 ID 的列表(包括各自的日期)。"yes"为了澄清起见,从一个月到下个月,我严格按时间顺序说话 - data.frame 中日期的排名应该是无关紧要的。因此,例如,如果在 2010 年 1 月 31 日存在具有相反分类器的相同 ID 的条目,则给定 ID 的更改可能仅在 2010 年 2 月 28 日发生。理想情况下,"no"如果ID "3" 具有on 2010-03-31"yes""yes""no""yes" CLASSIFIER"no" CLASSIFIER在 2010 年 4 月 30 日,列表应注明 ID“3”、“2010 年 4 月 30 日”和“是对否”之类的内容。第 3 行和第 4 行中的 ID“4”不符合更改条件,因为按时间顺序,从一个月到下个月没有发生更改。

有人可以帮我解决这个问题吗?

非常感谢您的帮助!

亲切的问候,

C。

标签: r

解决方案


我对您的预期输出并不完全清楚,但也许这样的事情会让您开始?

library(tidyverse)
Data %>%
    group_by(ID) %>%
    mutate(status = if_else(
        CLASSIFIER != lag(CLASSIFIER),
        sprintf("change: %s to %s", lag(CLASSIFIER), CLASSIFIER),
        "nochange"))
## A tibble: 50 x 4
## Groups:   ID [9]
#   DATE          ID CLASSIFIER status
#   <date>     <int> <fct>      <chr>
# 1 2010-04-30     3 no         NA
# 2 2010-07-31     3 yes        change: no to yes
# 3 2010-02-28     9 no         NA
# 4 2010-02-28     1 yes        NA
# 5 2010-10-31     2 no         NA
# 6 2010-07-31     5 yes        NA
# 7 2010-04-30     6 yes        NA
# 8 2010-12-31     3 no         change: yes to no
# 9 2010-08-31     4 yes        NA
#10 2010-01-31     1 no         change: yes to no
## … with 40 more rows

交叉检查:对于第 1 行和第 2 行之间和之间ID=3的更改。CLASSIFIER="no"对于第 4 行和第 10 行中的更改。"yes"Date="2010-04-03"Date="2010-07-31"ID=1CLASSIFIER="yes""no"


推荐阅读