Как переклассифицировать / заменить значения на основе приоритета при наличии повторов - PullRequest
1 голос
/ 14 марта 2019

У меня есть df, где value указывает на статус drug:

g1 = data.frame ( 
    drug = c('a','a','a','d','d'),
    value = c('fda','trial','case','case','pre')
)

drug value
1    a   fda
2    a trial
3    a  case
4    d  case
5    d   pre

Так что для лекарств я хочу заменить любое повторение drug на основе следующего порядка приоритета для value:

fda > trial > case > pre 

Так, например, если лекарство d является «случаем», а также «до», все случаи d будут реклассифицированы как «случай». Финальный стол должен выглядеть следующим образом.

  drug value
1    a   fda
2    a   fda
3    a   fda
4    d  case
5    d  case

Как это сделать, не обходя каждый препарат и не выясняя приоритет, а затем заменяя его?

Ответы [ 3 ]

3 голосов
/ 14 марта 2019

Аналогично ответу @ Вэнь-Бена, с функциями base вы также можете выполнять:

g1$value <- factor(g1$value, levels = c("fda", "trial", "case", "pre"))
g1 <- g1[order(g1$value),]
g1$value <- g1[match(g1$drug, g1$drug), "value"]
3 голосов
/ 14 марта 2019

Поскольку это порядковая переменная, вы можете сделать g1$value фактором ordered в качестве соответствующего class. Затем вы можете использовать такие функции, как min и max, как если бы вы были числовыми:

g1$value <- ordered(g1$value, levels = c("fda", "trial", "case", "pre"))
g1$value
#[1] fda   trial case  case  pre  
#Levels: fda < trial < case < pre
g1$value <- ave(g1$value, g1$drug, FUN=min)
g1
#  drug value
#1    a   fda
#2    a   fda
#3    a   fda
#4    d  case
#5    d  case

или dplyr говорят:

g1 %>%
  mutate(value = ordered(value, levels = c("fda", "trial", "case", "pre"))) %>%
  group_by(drug) %>%
  mutate(value = min(value))

Порядок в наборе данных и диапазон значений, присутствующих в любой группе drug, не должны влиять на этот результат:

g2 = data.frame ( 
    drug = c( "a","a","a","d","d","e","e","e"),
    value = c("fda","trial","case","case","pre","pre","fda","case")
)

#  drug value
#1    a   fda
#2    a trial
#3    a  case
#4    d  case
#5    d   pre
#6    e   pre
#7    e   fda
#8    e  case

g2 %>%
  mutate(value = ordered(value, levels = c("fda", "trial", "case", "pre"))) %>%
  group_by(drug) %>%
  mutate(value = min(value))

## A tibble: 8 x 2
## Groups:   drug [3]
#  drug  value
#  <fct> <ord>
#1 a     fda  
#2 a     fda  
#3 a     fda  
#4 d     case 
#5 d     case 
#6 e     fda  
#7 e     fda  
#8 e     fda 
3 голосов
/ 14 марта 2019

Обновление с использованием карты vector, что я делал раньше, так как я не хочу менять тип столбцов.

mapvect=c(1,2,3,4)
names(mapvect)=c('pre','case','trial','fda')
g1$helpkey=mapvect[g1$value]

g1 %>% group_by(drug) %>% arrange(value)%>% dplyr::mutate(value=value[helpkey==max(helpkey)])
# A tibble: 5 x 3
# Groups:   drug [2]
drug value helpkey
<chr> <chr>   <dbl>
1     a   fda       2
2     d  case       2
3     a   fda       4
4     d  case       1
5     a   fda       3
...