>我有一个带有"DATE"列,"ID"列和"CLASSIFIER"列的数据帧,如下所示:
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"
更改为"no"
或从"no"
更改为"yes"
从一个月更改为下一个月的ID(包括相应的日期)。为了澄清起见,从一个月到下个月,我严格按时间顺序说话 - data.frame 中日期的排名应该是无关紧要的。因此,例如,如果 2010-01-31 上存在具有相反分类器的相同 ID 的条目,则给定 ID 的更改可能仅在 2010-02-28 发生。理想情况下,该列表还将说明更改的性质(即从"no"
到"yes"
或从"yes"
到"no"
) 从上面的输出示例(前两行)来看,如果 ID "3" 在 2010-03-31 上具有"yes"
CLASSIFIER
,在 2010-04-30 上具有"no"
CLASSIFIER
,则列表应声明 ID "3"、"2010-04-30"和类似"是到否"的内容。第 3 行和第 4 行中的 ID "4"不符合更改的条件,因为从时间顺序讲,更改不是从一个月到下一个月发生的。
有人可以帮我吗?
提前非常感谢您的帮助!
亲切问候
三.
我不完全清楚你的预期输出,但也许这样的事情会让你开始?
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
交叉检查:对于ID=3
,第 1 行和第 2 行中Date="2010-04-03"
和Date="2010-07-31"
之间的CLASSIFIER="no"
更改为"yes"
。对于ID=1
,第 4 行和第 10 行的CLASSIFIER="yes"
更改为"no"
。