R: Определите для каждой группы номер строки, если значение в столбце лежит между возможной парой значений в двух других столбцах. - PullRequest
0 голосов
/ 03 мая 2018

У меня есть вопрос, который может быть простым, но я просто не могу его понять. Пример моего фрейма данных выглядит так:

> df.corrected
   Grp Grp.ind ini.1 fin.1 ini.2 fin.2 
1    A     A.1     0     5     0     5 
2    A     A.2     5    10     5    25 
3    A     A.3    10    15    NA    NA 
4    A     A.4    15    26    NA    NA 
5    A     A.5    26    28    NA    NA 
6    A     A.6    28    30    25    30 
7    B     B.1     0    15     0    10 
8    B     B.2    NA    NA    10    20 
9    B     B.3    15    20    20    25 
10   B     B.4    20    31    25    30 
11   B     B.5    31    50    30    50 

Я хочу посмотреть в каждой группе номер строки, в которой ini.1 для каждого наблюдения лежит между возможными значениями ini.2 и fin.2 (т.е. ini.2 <= ini.1 <fin.2, для всех пары ini.2, fin.2). Я хочу знать номер строки, чтобы создать новый идентификатор grp_ind. Вывод моего желания должен выглядеть так: </p>

> df.corrected
   Grp Grp.ind ini.1 fin.1 ini.2 fin.2 rownum New.Grp.ind
1    A     A.1     0     5     0     5      1         A.1
2    A     A.2     5    10     5    25      2         A.2
3    A     A.3    10    15    NA    NA      2         A.2
4    A     A.4    15    26    NA    NA      2         A.2
5    A     A.5    26    28    NA    NA      6         A.6
6    A     A.6    28    30    25    30      6         A.6
7    B     B.1     0    15     0    10      1         B.1
8    B     B.2    NA    NA    10    20     NA         B.2
9    B     B.3    15    20    20    25      2         B.2
10   B     B.4    20    31    25    30      3         B.3
11   B     B.5    31    50    30    50      5         B.5

Пока я пробовал:

df.corrected<-df %>%
  group_by(Grp) %>%
  mutate(rownum=ifelse(!(ini.1 >=ini.2 & ini.1 < fin.2),
                   NA, row_number())) %>%
  mutate(rownum=ifelse(is.na(rownum),
                   row_number(which((ini.1 >=(ini.2%in%ini.2)) & (ini.1 < (fin.2%in%fin.2)))),rownum)) %>%
  mutate(New.Grp.ind = Grp.ind[rownum])

, а также удаление, которое () во втором mutate () и у меня не было никакого успеха. Поскольку мой фрейм данных содержит более 6 тыс. Наблюдений, я хочу гибкое решение без использования na.locf. Я пробовал это решение раньше и не очень хорошо работает во всем наборе данных.

У кого-нибудь есть рекомендации по решению этой проблемы?

Заранее благодарю всех за помощь.

1 Ответ

0 голосов
/ 04 мая 2018

Подход, использующий dplyr, заключается в самостоятельном присоединении df.corrected к Grp и последующем применении filter для удовлетворения правил, указанных в OP. Это обеспечит New.Grp.ind для соответствующих условий. Наконец, для строк, которые не могут соответствовать правилам сопоставления, мы должны объединиться назад (используя right_join) с df.corrected на Grp и Grp.ind.

Примечание: Я предположил, что Grp + Grp.ind представляет уникальную строку в данных. Если нет, то row number следует добавить в данные, которые можно использовать как часть right_join.

library(dplyr)

df.corrected %>% inner_join((df.corrected %>% group_by(Grp) %>%
        mutate(rownum= row_number())), by="Grp") %>%
  filter(ini.1.x >=ini.2.y & ini.1.x < fin.2.y) %>%
  select( Grp, Grp.ind = Grp.ind.x, ini.1 = ini.1.x, fin.1 = fin.1.x, ini.2 = ini.2.x, 
           fin.2 = fin.2.x, rownum, New.Grp.ind = Grp.ind.y) %>%
  right_join(df.corrected, by=c("Grp","Grp.ind")) %>%
  select( Grp, Grp.ind, ini.1 = ini.1.x, fin.1 = fin.1.x, ini.2 = ini.2.x, fin.2 = fin.2.x,
         rownum, New.Grp.ind) %>%
  mutate(New.Grp.ind = coalesce(New.Grp.ind, Grp.ind))

#    Grp Grp.ind ini.1 fin.1 ini.2 fin.2 rownum New.Grp.ind
# 1    A     A.1     0     5     0     5      1         A.1
# 2    A     A.2     5    10     5    25      2         A.2
# 3    A     A.3    10    15    NA    NA      2         A.2
# 4    A     A.4    15    26    NA    NA      2         A.2
# 5    A     A.5    26    28    NA    NA      6         A.6
# 6    A     A.6    28    30    25    30      6         A.6
# 7    B     B.1     0    15     0    10      1         B.1
# 8    B     B.2    NA    NA    NA    NA     NA         B.2
# 9    B     B.3    15    20    20    25      2         B.2
# 10   B     B.4    20    31    25    30      3         B.3
# 11   B     B.5    31    50    30    50      5         B.5

Данные:

df.corrected <- read.table(text = 
"Grp Grp.ind ini.1 fin.1 ini.2 fin.2 
1    A     A.1     0     5     0     5 
2    A     A.2     5    10     5    25 
3    A     A.3    10    15    NA    NA 
4    A     A.4    15    26    NA    NA 
5    A     A.5    26    28    NA    NA 
6    A     A.6    28    30    25    30 
7    B     B.1     0    15     0    10 
8    B     B.2    NA    NA    10    20 
9    B     B.3    15    20    20    25 
10   B     B.4    20    31    25    30 
11   B     B.5    31    50    30    50",
header = TRUE, stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...