我在数据框中有很长的日期,列出了不同患者ID的日期。一位患者可以在列表中出现多次。像这样:
ID dates
1 2016-01-10
1 2016-02-10
1 2017-01-10
1 2018-02-10
1 etc
2
2
2
2
3
3
3
3
我基本上想创建一个新列,为每位患者每1年标记一次:
ID dates oneyear
1 2016-01-10 0
1 2016-02-10 NA
1 2017-01-10 1
1 2018-02-10 1
1 2018-02-11 NA
2 (new) 2012-02-03 0
2 2012-02-03 NA
2 2013-02-03 1
2
3
3
3
3
因此,我希望每个新患者都为0,同年不适用,新的一年或接近一年(可能是11个月)时为1。我将如何在R中执行此操作?
答案 0 :(得分:0)
也许是这样?
一些数据(这是您发布时应具有的可复制示例):
library(tidyverse)
library(lubridate)
df2 <- df %>%
mutate(year = year(dates)) %>% #creates the year column (takes the year from dates)
mutate(prev_year = lag(year)) %>% #lag of the year column by one row
mutate(lag_id = lag(id)) %>% #lag of id by one row
mutate(one_year = if_else(lag_id != id, NA_real_, year - prev_year)) #calculates the diff in years
这是什么:
# A tibble: 10 x 6
id dates year prev_year lag_id one_year
<dbl> <date> <dbl> <dbl> <dbl> <dbl>
1 1 2017-01-01 2017 NA NA NA
2 1 2017-01-02 2017 2017 1 0
3 1 2018-02-02 2018 2017 1 1
4 2 2017-01-01 2017 2018 1 NA
5 2 2017-01-02 2017 2017 2 0
6 2 2018-02-02 2018 2017 2 1
7 3 2016-01-01 2016 2018 2 NA
8 3 2017-01-02 2017 2016 3 1
9 3 2017-02-02 2017 2017 3 0
10 3 2018-03-02 2018 2017 3 1
我想这就是你的追求。
答案 1 :(得分:0)
OP要求“ 检查接近1年的最接近值”,但是赞赏answer,该检查仅检查年份是否已更改。因此,目前尚不清楚OP是否要检查大约一年或只是一个新日期之间的日期差。
例如,在2012-12-31和2013-01-01之间,只有一天的差异,但年份已更改。另一方面,2013-01-01和2013-12-31位于同一日历年内,但相差将近一年。
因此,下面的解决方案针对年份的变化(与天数无关)返回newyear
,对于日期差异大约返回oneyear
。一年(与日历年无关)。
正如OP提到的11个月接近一年,我特意选择11/12 * 365 = 334.6天作为阈值。因此,任何大于此值的日期差都被视为大于“一年”。请调整此值以满足您的要求。
library(dplyr)
threshold_days <- 11/12*365
DF %>%
arrange(ID, dates) %>% # not required if data are already ordered
group_by(ID) %>%
mutate(newyear = c(0, NA^(1 - diff(lubridate::year(dates)) >= 1)),
oneyear = c(0, NA^(1 - (diff(dates, units = "days") > threshold_days))))
ID dates newyear oneyear <dbl> <date> <dbl> <dbl> 1 1 2016-01-10 0 0 2 1 2016-02-10 NA NA 3 1 2017-01-10 1 1 4 1 2018-02-10 1 1 5 1 2018-02-11 NA NA 6 2 2012-12-31 0 0 7 2 2013-01-01 1 NA 8 3 2013-01-01 0 0 9 3 2013-12-31 NA 1 10 4 2013-12-31 0 0 11 4 2015-02-01 1 1 12 4 2015-02-02 NA NA
请注意,用例newyear
2和3分别在oneyear
和ID
之间有所不同。用例ID
4证明如果间隔超过一年,则返回1
。
OP已请求返回NA
来指示可以忽略的数据差异。为了在没有if_else()
的情况下实现这一点,使用了幂运算。 NA^0
是1
,而NA^1
(或任何其他指数)是NA
。
DF <- readr::read_table(
"ID dates
1 2016-01-10
1 2016-02-10
1 2017-01-10
1 2018-02-10
1 2018-02-11
2 2012-12-31
2 2013-01-01
3 2013-01-01
3 2013-12-31
4 2013-12-31
4 2015-02-01
4 2015-02-02")
恕我直言,我发现OP的选择是用NA
表示小的差距,并用ID
标记0
的第一次出现是有些人为的。在R中,0
和1
可以看作是逻辑值FALSE
和TRUE
的整数等效项,而NA
通常表示缺失值。
因此,我的建议是对每个新患者(遗漏差异)使用NA
,对同一年或少于一年的患者使用0
,对新患者使用1
或日期差大于一年。这将大大简化代码。
threshold_days <- 11/12*365
DF %>%
arrange(ID, dates) %>% # not required if data are already ordered
group_by(ID) %>%
mutate(newyear = c(NA, diff(lubridate::year(dates)) >= 1),
oneyear = c(NA, diff(dates, units = "days") > threshold_days))
ID dates newyear oneyear <dbl> <date> <lgl> <lgl> 1 1 2016-01-10 NA NA 2 1 2016-02-10 FALSE FALSE 3 1 2017-01-10 TRUE TRUE 4 1 2018-02-10 TRUE TRUE 5 1 2018-02-11 FALSE FALSE 6 2 2012-12-31 NA NA 7 2 2013-01-01 TRUE FALSE 8 3 2013-01-01 NA NA 9 3 2013-12-31 FALSE TRUE 10 4 2013-12-31 NA NA 11 4 2015-02-01 TRUE TRUE 12 4 2015-02-02 FALSE FALSE