【发布时间】:2019-01-16 06:07:51
【问题描述】:
我正在尝试创建一个程序,在最多 900 天的 30 天范围内选择最近的一天(1-30,31-60,61-90......871- 900)。我正在使用 R 版本 3.3.3。
这是我拥有的数据集的一个示例:
have <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 4L,
5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L,
9L, 9L, 9L, 9L, 9L, 9L), time.to.first = c(0L, 78L, 293L, 0L,
63L, 0L, 89L, 0L, 11L, 27L, 0L, 28L, 0L, 29L, 0L, 31L, 381L,
778L, 0L, 28L, 69L, 96L, 466L, 0L, 28L, 56L, 98L, 154L, 220L,
294L, 395L, 507L), visit = c(1L, 2L, 3L, 1L, 2L, 1L, 2L, 1L,
2L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L)), .Names = c("id", "time.to.first",
"visit"), row.names = c(NA, 32L), class = "data.frame")
这是我想要的:
want <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 4L,
5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L,
9L, 9L, 9L, 9L, 9L, 9L), time.to.first = c(0L, 78L, 293L, 0L,
63L, 0L, 89L, 0L, 11L, 27L, 0L, 28L, 0L, 29L, 0L, 31L, 381L,
778L, 0L, 28L, 69L, 96L, 466L, 0L, 28L, 56L, 98L, 154L, 220L,
294L, 395L, 507L), visit = c(1L, 2L, 3L, 1L, 2L, 1L, 2L, 1L,
2L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L), time.window = structure(c(1L,
11L, 5L, 1L, 11L, 1L, 11L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 6L,
7L, 12L, 1L, 2L, 11L, 13L, 9L, 1L, 2L, 6L, 13L, 3L, 4L, 5L, 8L,
10L), .Label = c("", "1-30", "151-180", "211-240", "271-300",
"31-60", "361-390", "391-420", "451-480", "481-510", "61-90",
"751-780", "91-120"), class = "factor")), .Names = c("id", "time.to.first",
"visit", "time.window"), row.names = c(NA, 32L), class = "data.frame")
我能够弄清楚如何使用一系列ifelse 语句和filter 和left_join 在第一个日期范围(1-30 天)中创建日期范围:
x <- 1
y <- 30
df <- have %>% group_by(id) %>%
mutate(flag = ifelse(time.to.first >= x & time.to.first <= y,max(visit),""),
flag2 = ifelse(flag == max(flag) & flag != "",1,"")) %>%
filter(flag > 0 & flag2 == 1) %>%
filter(visit == max(visit)) %>%
mutate(time = paste(x,"-", y, sep = "")) %>%
dplyr::select(time, id, visit) %>%
left_join(have, ., by = c("id","visit"))
我在想我可以为 x 和 y 变量使用双嵌套 for 循环,以便创建一个可以处理其余日期范围的程序,但我知道嵌套循环可能不是最有效的方法来解决这个问题。
我试图想办法让程序更健壮一点,这样我就可以改变窗口的时间(从 30 天到 90,180,360 等...),但我不知道如何解决这个问题。
我不想要为我编写的代码,但会喜欢你认为可能有用的函数或示例的想法。我一直很难找到此类程序的更多信息,因此任何其他链接都会有所帮助!
【问题讨论】:
-
have %>% mutate(x = cut(time.to.first, seq(0, ceiling(max(time.to.first)/30)*30, by=30)))?相关:stackoverflow.com/q/5746544/1191259 -
哇,这太棒了!这让我完成了 90% 的工作,代码更加优雅。我将不得不阅读切割和天花板。
-
library
lubridate具有有用的ceiling_date和floor_date函数,并允许您使用天或月等持续时间。 -
如果范围是 1-900,您希望如何处理
0?应该计入1-30还是NA? -
Na 会很好@Frank 似乎已经回答了我的大部分问题。我刚刚完成了修改,所以我将其添加为答案