按 ID 和结果分组,取特定结果的最早日期并分配数字(即结果 1、结果 2)
Posted
技术标签:
【中文标题】按 ID 和结果分组,取特定结果的最早日期并分配数字(即结果 1、结果 2)【英文标题】:Group by ID and Outcome and take the earliest earliest Dates of specific outcomes and assign numbers (i.e outcome1, outcome2) 【发布时间】:2022-01-02 07:17:02 【问题描述】:抱歉,如果我没有清楚地解释这一点。 但我有以下数据集:
mydata = data.frame (Id =c (1,1,1,1,1,1,1,1,2,2,2,2),
Date = c("2001-01-31", "2001-02-13","2001-05-31",
"2001-06-02","2018-01-31","2018-03-31","2018-07-31",
"2019-04-04","2014-01-31","2014-02-02","2014-04-31",
"2014-05-18"),Outcome = c("CR","CR","Relapse","Relapse",
"CR","CR","CR","Relapse","CR", "CR","Relapse","CR"))
输出以下内容。如您所见,每位患者在不同时间处于某些阶段,我想记录每位患者每个新阶段开始的最早日期。然后我想将这些阶段重命名为 CR1、Relapse1、CR2、Relapse2 等等。
Id Date Outcome
1 2001-01-31 CR
1 2001-02-13 CR
1 2001-05-31 Relapse
1 2001-06-02 Relapse
1 2018-01-31 CR
1 2018-03-31 CR
1 2018-07-31 CR
1 2019-04-04 Relapse
2 2014-01-31 CR
2 2014-02-02 CR
2 2014-04-31 Relapse
2 2014-05-18 CR
这是我想要达到的输出:
Id CR1 Relapse1 CR2 Relapse2
1 2001-01-31 2001-05-31 2018-01-31 2019-04-04
2 2014-01-31 2014-04-31 2014-05-18 NA
我不太确定从哪里开始提出这个问题,如果有任何帮助,我将不胜感激!谢谢各位!
【问题讨论】:
您是指每个 ID 年份结果组合中最早的一个吗?还是每个 ID 结果的最早和最晚? 最终结果变量的顺序重要吗?即,如果您获得 CR1、CR2、Relapese1、Relapse2,这有关系吗? @Macosso 每个 ID 和结果组合的最早日期 在它们切换到另一个结果之前。 @NicolásVelásquez 是的,复发前的第一个 CR 应标记为 CR1,之后应标记为 relapse1。如果他们在复发后再次达到CR,应该是CR2等等 对此的后续问题,是否有可能仅在看到第一个 CR 后才开始计数?因此,如果一个 id 在 CR 之前有 Relapse 将被忽略,然后在第一个 CR 之后的第一次复发将被视为 Relapse 1?谢谢!! —— 【参考方案1】:使用tidyverse
,您可以尝试以下操作。
(如果需要,首先 arrange
和 Date
按时间顺序排列。)
根据Outcome
列中的变化创建一个分组值(从缓解到复发,反之亦然)。为了方便起见,我使用了data.table
中的rleid
,并创建了一个临时列Grp
。例如:
Id Date Outcome Grp
<dbl> <chr> <chr> <int>
1 1 2001-01-31 CR 1
2 1 2001-02-13 CR 1
3 1 2001-05-31 Relapse 2
4 1 2001-06-02 Relapse 2
5 1 2018-01-31 CR 3
6 1 2018-03-31 CR 3
7 1 2018-07-31 CR 3
8 1 2019-04-04 Relapse 4
9 2 2014-01-31 CR 1
10 2 2014-02-02 CR 1
11 2 2014-04-31 Relapse 2
12 2 2014-05-18 CR 3
您可以看到,在每个Id
中,当Outcome
更改时,Grp
会增加。这样,具有相同Outcome
的后续日期将包含在相同的Grp
中。
.add
参数允许我们将 Grp
添加到之前的分组中,即 Id
。因此,现在按Grp
和Id
分组,然后您可以slice
第一行。 slice(1)
或 slice(n = 1)
将在组内保留 1 行。在这种情况下,我们同时按Id
和Grp
进行分组,因此对于给定的Grp
和Id
组合只会保留1 行。
最后,您可以添加一个允许所描述的宽输出的行号(CR 和复发的连续数字序列:1、2、3、4...)。在这种情况下,我们group_by
同时Id
和Outcome
,并为这个组合连续编号日期。如果需要,pivot_wider
会将数据转换为宽格式。
library(data.table)
library(tidyverse)
mydata %>%
group_by(Id) %>%
mutate(Grp = rleid(Outcome)) %>%
group_by(Grp, .add = T) %>%
slice(1) %>%
group_by(Id, Outcome) %>%
mutate(n = row_number()) %>%
pivot_wider(id_cols = Id, names_from = c(Outcome, n), values_from = Date)
输出
Id CR_1 Relapse_1 CR_2 Relapse_2
<dbl> <chr> <chr> <chr> <chr>
1 1 2001-01-31 2001-05-31 2018-01-31 2019-04-04
2 2 2014-01-31 2014-04-31 2014-05-18 NA
【讨论】:
谢谢!我试过了,但一直收到以下错误:``` 错误:在group_by()
中添加计算列时出现问题。 x mutate()
输入 Grp
有问题。 x找不到函数“rleid”ℹ输入Grp
是rleid(Outcome)
```
@Ben,啊,你比我快 3 分钟 :( 无论如何我只能使用子集和 shitf() 函数来解决它。你能解释一下这条线:group_by(Grp = rleid(Outcome), .add = T) %>%
做什么? 还有slice(1)
。
@Ben 效果很好,非常感谢!
@Ben 非常有帮助!
已编辑,以便 rleid
编号随着 Id
的更改重新启动。以上是关于按 ID 和结果分组,取特定结果的最早日期并分配数字(即结果 1、结果 2)的主要内容,如果未能解决你的问题,请参考以下文章