Благодаря @wibeasley я нашел решение, хотя и не короткое, оно довольно хорошо читаемое:
df1 <- df %>%
filter(Group=='C') %>%
mutate( TestSeq = case_when(
percent_rank(ID_code)<0.25 & Seq=='A' ~ 'MS',
percent_rank(ID_code)<0.25 & Seq=='AM' ~ 'SS',
percent_rank(ID_code)<0.5 & Seq=='AM' & 0.25 <= percent_rank(ID_code) ~ 'MS',
percent_rank(ID_code)<0.5 & Seq=='A' & 0.25 <= percent_rank(ID_code) ~ 'SS',
percent_rank(ID_code)<0.75 & Seq=='B' & 0.5 <= percent_rank(ID_code) ~ 'MS',
percent_rank(ID_code)<0.75 & Seq=='BM' & 0.5 <= percent_rank(ID_code) ~ 'SS',
Seq=='BM' & 0.75 <= percent_rank(ID_code) ~ 'MS',
Seq=='B' & 0.75 <= percent_rank(ID_code) ~ 'SS',
TRUE ~ 'DS'
)
)
full_join(df,df1)
Учитывая все подсказки от wibeasley, я изменил код на это:
df1a <- df %>%
#filter(Group=='C') %>%
mutate(
code_rank = case_when(
Group=='C' ~ percent_rank(ID_code)
)
) %>%
mutate(
TestSeq = case_when(
is.na(Group) | (Group!='C') ~ '0', # Or whatever
Seq=='A' & (code_rank < .25) ~ 'MS',
Seq=='A' & (code_rank < .50) ~ 'SS',
Seq=='A' & (code_rank < Inf) ~ 'DS',
Seq=='AM' & (code_rank < .25) ~ 'SS',
Seq=='AM' & (code_rank < .50) ~ 'MS',
Seq=='AM' & (code_rank < Inf) ~ 'DS',
Seq=='B' & (code_rank < .50) ~ 'DS',
Seq=='B' & (code_rank < .75) ~ 'MS',
Seq=='B' & (code_rank < Inf) ~ 'SS',
Seq=='BM' & (code_rank < .50) ~ 'DS',
Seq=='BM' & (code_rank < .75) ~ 'SS',
Seq=='BM' & (code_rank < Inf) ~ 'MS'
)
) #%>%
dplyr::select(-code_rank)
Однако у этого есть одна проблема.Code_rank рассчитывается по всем идентификаторам, но должно рассчитываться только по группе == 'C'.Есть ли способ поместить фильтр в mutate / into case_when?Я также заметил, что процент_ранка рассчитывается как 4/7, потому что у меня есть дубликаты.Мое новое решение:
df1a <- df %>%
filter(Group=='C') %>%
filter(!duplicated(ID)) %>%
mutate(
code_rank = percent_rank(ID_code)
)
df <- left_join(df,df1a)
df <- df %>% group_by(ID) %>% fill(code_rank) #get code_rank in all rows
#View(df)
df1b <- df %>%
filter(Group=='C') %>%
mutate(
TestSeq = case_when(
Seq=='A' & (code_rank < .25) ~ 'MS',
Seq=='A' & (code_rank < .50) ~ 'SS',
Seq=='A' & (code_rank < Inf) ~ 'DS',
Seq=='AM' & (code_rank < .25) ~ 'SS',
Seq=='AM' & (code_rank < .50) ~ 'MS',
Seq=='AM' & (code_rank < Inf) ~ 'DS',
Seq=='B' & (code_rank < .25) ~ 'DS',
Seq=='B' & (code_rank < .75) ~ 'MS',
Seq=='B' & (code_rank < Inf) ~ 'SS',
Seq=='BM' & (code_rank < .50) ~ 'DS',
Seq=='BM' & (code_rank < .75) ~ 'SS',
Seq=='BM' & (code_rank < Inf) ~ 'MS'
)
)
df <- select(left_join(df,df1b),-code_rank)