我有一些数据包含ID,日期和相关ID和开始日期组合的整数值,每个ID有多个日期。
我想创建一个列,指示:
1)如果ID的整数中的&> = 14,或者12个月内有4个单独的整数,则告诉我。
这里有一个类似的问题,但我的类别有点复杂: Create new column based on condition that exists within a rolling date
任何帮助非常感谢!
以下是一些数据的输入:
structure(list(ID = c("90939293", "90963328", "90092983",
"90032926", "90944838", "90092983", "90062392", "90224939", "90202398",
"90926203", "90936043", "90329263", "90944838", "90232033", "90980903",
"90924463", "90299292", "90933383", "90209349", "90092983", "90022988",
"90022293", "90933383", "90092983", "90299240", "90963033", "90004923",
"90292998", "90986096", "90980903", "90336692", "90933383", "90022988",
"90069992", "90062392", "90209248", "90924463", "90092983", "90933383",
"90022293", "90062392", "90004923", "90233269", "90329263", "90229202",
"90309943", "90299292", "90036820", "90329263", "90232033", "90329263",
"90336692", "90963033", "90224939", "90924463", "90069992", "90092983",
"90934923", "90926203", "90222333", "90092983", "90299292", "90202398",
"90004923", "90233269", "90926203", "90222333", "90224939", "90232033",
"90933383", "90022293", "90022988", "90934923", "90069992", "90329263",
"90209349", "90022293", "90309943", "90299240", "90022293", "90336692",
"90020334", "90933383", "90290384", "90224939", "90980903", "90299240",
"90299292", "90202398", "90022346"), Date = structure(c(15972,
16009, 16010, 16010, 16007, 16010, 16006, 16010, 16007, 16008,
15997, 16007, 16007, 16002, 16008, 16006, 16006, 16006, 16009,
16010, 16006, 16006, 16006, 16010, 15995, 16008, 16008, 16010,
16009, 16008, 16010, 16006, 16006, 16009, 16006, 16006, 16006,
16010, 16006, 16006, 16006, 16008, 16009, 16007, 16010, 16007,
16006, 16009, 16007, 16002, 16007, 16010, 16008, 16010, 16006,
16009, 16010, 15936, 16008, 16008, 16010, 16006, 16007, 16008,
16009, 16008, 16008, 16010, 16002, 16006, 16006, 16006, 15936,
16009, 16007, 16009, 16006, 16007, 15995, 16006, 16010, 16006,
16006, 16010, 16010, 16008, 15995, 16006, 16007, 16008), class = "Date"),
Integer = c(39, 2, 1, 1, 4, 1, 5, 1, 4, 3, 14, 4, 4, 9,
3, 5, 5, 5, 2, 1, 5, 5, 5, 1, 16, 3, 3, 1, 2, 3, 1, 5, 5,
2, 5, 5, 5, 1, 5, 5, 5, 3, 2, 4, 1, 4, 5, 2, 4, 9, 4, 1,
3, 1, 5, 2, 1, 75, 3, 3, 1, 5, 4, 3, 2, 3, 3, 1, 9, 5, 5,
5, 75, 2, 4, 2, 5, 4, 16, 5, 1, 5, 5, 1, 1, 3, 16, 5, 4,
3)), .Names = c("ID", "Date", "Integer"
), row.names = c("200086", "200066", "200050", "200064", "200078",
"200050.1", "200069", "200082", "200083", "200053", "200056",
"200055", "200078.1", "200079", "200051", "200089", "200052",
"200057", "200061", "200050.2", "200060", "200080", "200057.1",
"200050.3", "200068", "200071", "200070", "200059", "200062",
"200051.1", "200067", "200057.2", "200060.1", "200072", "200069.1",
"200073", "200089.1", "200050.4", "200057.3", "200080.1", "200069.2",
"200070.1", "200081", "200054", "200063", "200075", "200052.1",
"200074", "200054.1", "200079.1", "200055.1", "200067.1", "200071.1",
"200082.1", "200089.2", "200072.1", "200050.5", "200084", "200053.1",
"200088", "200050.6", "200052.2", "200083.1", "200070.2", "200081.1",
"200053.2", "200088.1", "200082.2", "200079.2", "200057.4", "200080.2",
"200060.2", "200084.1", "200072.2", "200055.2", "200061.1", "200080.3",
"200075.1", "200068.1", "200080.4", "200067.2", "200065", "200057.5",
"200090", "200082.3", "200051.2", "200068.2", "200052.3", "200083.2",
"200076"), class = "data.frame")
答案 0 :(得分:2)
这里是你要求的东西。现在,查找其Integer大于14的ID的ID就像按ID分组并检查每个ID的Integer列的总和是> = 14还是dplyr:df %>% group_by(ID) %>% mutate(conditional = sum(Integer) >= 14)
一样简单。在12个月内找到一个(至少?)4的ID显然更难。我的解决方案在计算窗口计数时遵循this回答。
只有一点需要注意:由于roll_sum
通过滚动行数来工作,我使用的解决方案依赖于每个ID每天只有一行。在您的示例数据框中,实际上有相同ID日期的多个条目,但它们似乎是重复的,因此我删除了它们。如果它们不是,并且需要针对sum(Integer) >= 14
的条件计算重复值,则可以预先将它们(而不是被移除)进行求和(例如:df %>% group_by(ID, Date) %>% summarize(Integer = sum(Integer))
),以便在那里&#39 ;每个日期每个ID只有一个条目。
library(dplyr)
library(tidyr)
library(RcppRoll)
df_tmp <- df
df <- df_tmp %>%
group_by(ID, Date) %>%
filter(n() == 1) %>% # this line removes duplicate columns
ungroup() %>%
complete(ID,
Date=seq(from=min(Date)-365,to=max(Date), by=1),
fill=list(Integer=0)) %>% # we use complete to add in a row for all IDs for every single date since a year before the first obs.
arrange(ID, Date) %>%
group_by(ID) %>%
mutate(roll_count = roll_sum(x = Integer != 0, n = 365, fill=0, align="right"), # this calculates the rolling sum using n = 365 as a stand-in for 12 months
conditional = sum(Integer) >= 14 || roll_count >= 4 ) %>%
ungroup() %>%
right_join(df, by = c("ID","Date", "Integer")) # right_join with the original data to remove dummy dates
希望这有帮助!
答案 1 :(得分:2)
将您的dput设为'x':
library(data.table)
setDT(x, key = "Date")
# test 1
x[, `:=` (
test1 = sum(Integer) >= 14
), by = ID]
# test2
y = x[, .(
count12 = uniqueN(Integer)
), by = .(start = Date, end = Date - 365)]
# combine
z = merge(x, y, by.x = "Date", by.y = "start")
z[, end := NULL]
z[, flag := test1 | count12 == 4]