2016-03-29 3 views
1

У меня есть dataframe, который выглядит как эта игрушка, например:R - Изменение значения на основе справки

Ind  ID RegionStart  RegionEnd Value  TN 
1  A  1    100   3  N 
1  A  101   200   2  N 
2  A  1    100   3  T 
2  A  101   200   2  T 
3  B  1    100   3  N 
3  B  101   200   2  N 
4  B  1    100   5  T 
4  B  101   200   5  T 

У меня 4 лиц, которые на самом деле 2 пары (ссылка, N, и при условии, Т) , Для простоты всего 2 пары и только 2 области. В моем реальном файле есть> 500 пар и> 60 000 регионов. Все регионы имеют одинаковое начало и конец, поэтому нет перекрытий.

То, что я хочу сделать, это MATCH индивиды на основе ID + region, и если

  • Value из N-человека в этом регионе! = 3 (не равно 3) &
  • в Value для N-индивидуальной & Т-индивидуального матча в этой области (например, N-Ind = 2 & Т-Ind = 2),

затем ч Анж соответствующая Value в обоих N & T индивидуумов 3.

Полученная таблица сверху будет:

Ind  ID RegionStart  RegionEnd Value  TN 
1  A  1    100   3  N 
1  A  101   200   3  N 
2  A  1    100   3  T 
2  A  101   200   3  T 
3  B  1    100   3  N 
3  B  101   200   2  N 
4  B  1    100   5  T 
4  B  101   200   5  T 

Обратите внимание, что ID=B, область 1-100 не изменилась Value потому, что N-х Value = 3; регион 101-200, не изменился, потому что Value s для N & T не были одинаковыми.

Я думал использовать dplyr для группы матчей, например:

df <- df %>% arrange(ID, Ind, RegionStart, TN) %>% group_by(ID) 

Или, возможно, с помощью data.table, но установка идентификатора в качестве ключа? Но я все еще не уверен, как легко сравнивать строки. Я все еще довольно новичок в dplyr & data.table, поэтому краткое объяснение команды было бы замечательным, если вы их используете. Не стесняйтесь использовать другой пакет. Однако данные довольно большие, поэтому они должны быть эффективными.

ответ

4

С data.table:

library(data.table) 
setDT(DF) 

DF[, Value := { 
    fixit = (Value[TN=="N"] != 3L) & (uniqueN(Value) == 1L) 
    if (fixit) 3L else Value 
}, by=.(ID, RegionStart)] 

Обратите внимание, что это изменит ваш первоначальный набор данных (а не просто возвращает измененную таблицу).


С dplyr:

library(dplyr) 
DF %>% group_by(ID, RegionStart) %>% 
    mutate(Value = { 
    fixit = (Value[TN=="N"] != 3L) & (n_distinct(Value) == 1L) 
    if (fixit) 3L else Value 
    }) 

Как это работает:uniqueN и n_distinct подсчитать число различных значений в векторе. Если оба элемента Value совпадают, то это вернет 1L.

Смежные вопросы