我從頭到尾跟蹤了一些人 A 和 B
df<-data.frame(id=c("A", "B"), start=as.Date(c("2015-01-01", "2013-01-01")), end=as.Date(c("2021-06-12", "2017-10-10")))
df
id start end
1 A 2015-01-01 2021-06-12
2 B 2013-01-01 2017-10-10
我想計算每個日歷年的跟進時間。例如,我 2013 年有 1 年(來自 B),2014 年有 1 年(來自 B),2015 年有 2 年(來自 A 和 B)等等。
我試圖將年份視為整數并計算每個人貢獻了多少年,但由于四舍五入錯誤,結果并不合理。
我試過
years<-NULL
for (i in 1:length(df$id)){
years<-c(years, as.character(as.Date(seq.Date(from = df$start[i], to = df$end[i], by = "day"))))
}
library(lubridate)
table(year(years))/365
2013 2014 2015 2016 2017 2018 2019 2020 2021
1.0000000 1.0000000 2.0000000 2.0054795 1.7753425 1.0000000 1.0000000 1.0027397 0.4465753
這是我試圖得到的答案,但在大資料中計算效率低下且速度非常慢。我想知道有沒有辦法在沒有回圈的情況下做到這一點?還是做得更有效?
uj5u.com熱心網友回復:
聽起來像是一個名為lubridate. 見示例:
順便說一句,我假設日期是年-月-日,因此ymd. 如果沒有,您可以使用ydm(year-day-month) 作為美國日期格式。
df<-data.frame(id=c("A", "B"), start=as.Date(c("2015-01-01", "2013-01-01")), end=as.Date(c("2021-06-12", "2017-10-10")))
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
library(tidyverse)
df %>%
mutate(across(start:end, ymd),
follow_up_years = interval(start, end)/years(1),
follow_up_months = interval(start, end)/months(1),
follow_up_days = interval(start, end)/days(1),
)
#> id start end follow_up_years follow_up_months follow_up_days
#> 1 A 2015-01-01 2021-06-12 6.443836 77.36667 2354
#> 2 B 2013-01-01 2017-10-10 4.772603 57.29032 1743
由reprex 包(v2.0.1)于 2021 年 10 月 28 日創建
編輯
我覺得我懂了。我想我們也可以只使用潤滑間隔:
df %>%
mutate(follow_up_2015 = interval(start, as_date("2015-01-01"))/years(1)) %>%
pull(follow_up_2015) %>%
sum()
#> [1] 2
由reprex 包(v2.0.1)于 2021 年 10 月 28 日創建
uj5u.com熱心網友回復:
我現在猜測您實際上不想舍入或截斷任何內容,因此這里有一個解決方案,該解決方案有效并提供類似于您的方法的輸出(更正 2016 年值):
func <- function(st, ed) {
stopifnot(length(st) == 1, length(ed) == 1)
stL <- as.POSIXlt(st)
edL <- as.POSIXlt(ed)
start_year <- 1900 stL$year
end_year <- 1900 edL$year
start_eoy <- as.POSIXlt(paste0(start_year, "-12-31"))
end_eoy <- as.POSIXlt(paste0(end_year, "-12-31"))
firstyear <- (start_eoy$yday - stL$yday) / start_eoy$yday
lastyear <- edL$yday / end_eoy$yday
data.frame(
year = seq(start_year, end_year),
n = c(firstyear, rep(1, max(0, end_year - start_year - 1)), lastyear)
)
}
基數R
aggregate(n ~ year, data = do.call(rbind, Map(func, df$start, df$end)), FUN = sum)
# year n
# 1 2013 1.0000000
# 2 2014 1.0000000
# 3 2015 2.0000000
# 4 2016 2.0000000
# 5 2017 1.7747253
# 6 2018 1.0000000
# 7 2019 1.0000000
# 8 2020 1.0000000
# 9 2021 0.4450549
dplyr
library(dplyr)
df %>%
with(Map(func, start, end)) %>%
bind_rows() %>%
group_by(year) %>%
summarize(n = sum(n))
# # A tibble: 9 x 2
# year n
# <int> <dbl>
# 1 2013 1
# 2 2014 1
# 3 2015 2
# 4 2016 2
# 5 2017 1.77
# 6 2018 1
# 7 2019 1
# 8 2020 1
# 9 2021 0.445
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/340141.html
上一篇:如何通過比較兩個公共列來識別僅存在于兩個資料集中之一中的行?
下一篇:ggplot只有黑點,沒有顏色
