2017-01-17 1 views
2

Я хотел бы выполнить вменения переменной, чтобы она была постоянной в каждом id. То есть var1 может иметь только одно отличное значение для каждого id.Как выполнить вменения переменной, учитывая количество вхождений значений для одной и той же переменной?

Одним из них является выполнение вменений с учетом количества вхождений значений существующей переменной, а также некоторых других условий.

df_old<- read.table(header = TRUE, text = " 
date  id var1 
25/01/2016 1 A 
02/05/2016 1 A 
20/03/2016 1 B 
13/07/2016 1 NA 
20/03/2016 2 B 
28/04/2016 2 C 
20/03/2016 3 B 
28/04/2016 3 OTHERS 
28/04/2016 3 OTHERS 
20/10/2016 4 NA 
28/11/2016 4 NA 
",stringsAsFactors=FALSE) 

Мы фокусируемся на var1 здесь. Внутри каждого id:

  1. Если var1 имеет либо A, B или C, то приписывать var1 со значением, которое происходит больше всего. например для id=1, он имеет два отличных значения var1 (A и B), поэтому мы приписываем его A, так как он встречается больше всего. Нанесите недостающее значение на A.
  2. Если var1 имеет либо A, B или C, и два различных var1 значений имеют одинаковое количество вхождений, то приписывать значение var1 с тем, что происходит последнее. Для id=2 он имеет один B и один C. Мы приписываем его C, так как соответствующая ему дата встречается последней.
  3. Если var1 содержит два различных значения один из этого является либо A/B/C и другой OTHERS, мы всегда приписывать используя A/B/C. Следовательно, для id=3 мы примем, используя B вместо OTHERS.
  4. Если var1 содержит только OTHERS, тогда он останется OTHERS.
  5. Для id=4, где он не имеет значений var1, они останутся пропущенными.

Таким образом, новый dataframe должен выглядеть следующим образом:

df_new<- read.table(header = TRUE, text = " 
date  id var1 
25/01/2016 1 A 
02/05/2016 1 A 
20/03/2016 1 A 
13/07/2016 1 A 
20/03/2016 2 C 
28/04/2016 2 C 
20/03/2016 3 B 
28/04/2016 3 B 
28/04/2016 3 B 
20/10/2016 4 NA 
28/11/2016 4 NA 
",stringsAsFactors=FALSE)` 

Я пытался выписать первый случай, но я не могу показаться, чтобы решить эту проблему и, следовательно, не может двигаться дальше других случаях.

library(dplyr) 
df_old %>% 
group_by(id,var1) %>% 
mutate(n=n()) %>% 
group_by(id) %>% 
mutate(var1=if_else(n==min(n),var1[max(n)],var1[max(n)])) 

или заменить последнюю строку с replace(var1,which(min(n)),var1[which(max(n))]))

Оба дают ошибки:

Error: invalid 'type' (closure) of argument"

Как это исправить?

+0

Что делать, если группа содержит только «ДРУГИЕ»? Должна ли новая переменная быть «ДРУГИЕ»? – Psidom

+0

@Psidom Да, я хотел бы, чтобы он оставался как «ДРУГИЕ». – HNSKD

ответ

2

вы можете использовать tidyverse функции:

dft %>% 
     group_by(id, var1) %>% 
     mutate(var2 = n()) %>% 
     mutate(var2 = if_else(var1 == "OTHERS", as.integer(0), as.integer(var2))) %>% 
     mutate(var2 = if_else(is.na(var2), as.integer(-1), as.integer(var2))) %>% 
     ungroup() %>% 
     group_by(id) %>% 
     arrange(desc(date)) %>% 
     mutate(var3 = var1[which.max(var2)]) %>% 
     arrange(id) %>% 
     select(date, id, var3) 

, который дает:

Source: local data frame [11 x 3] 
Groups: id [4] 

     date id var3 
     <chr> <int> <chr> 
1 25/01/2016  1  A 
2 20/03/2016  1  A 
3 13/07/2016  1  A 
4 02/05/2016  1  A 
5 28/04/2016  2  C 
6 20/03/2016  2  C 
7 28/04/2016  3  B 
8 28/04/2016  3  B 
9 20/03/2016  3  B 
10 28/11/2016  4 <NA> 
11 20/10/2016  4 <NA> 

Использовалась 0 и -1 для учета частот OTHERS и NA. Если вы предпочитаете другой порядок приоритетов, измените значения соответствующим образом.

+0

Спасибо, это здорово! Я полагаю, что присвоение чисел типа '0' для' OTHERS' и '-1' для' NA' упрощает вычисления. Кроме того, я думал, так как вы не можете организовать даты в каждой группе (https://github.com/hadley/dplyr/issues/2116), я подумал, что было бы лучше организовать «id», а затем 'desc (date) 'перед группировкой по' id'. Напр. 'arr (id, desc (date))%>% group_by (id)'. – HNSKD