Самый быстрый способ выбрать последние ненулевые значения для разных групп и столбцов - PullRequest
0 голосов
/ 01 ноября 2019

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

```

    issue_id  month day   FR   MR  SPR         superid
 1:   199779 200501   6              A 199779 - 200501
 2:   199779 200501  25      Baa1      199779 - 200501
 3:   199779 200505  11    A           199779 - 200505
 4:   199779 200605  23    A           199779 - 200605
 5:   199779 200706   7    A           199779 - 200706
 6:   199779 200805  19    A           199779 - 200805
 7:   199779 200904  20   A+           199779 - 200904
 8:   199779 201004  30   A+           199779 - 201004
 9:   199779 201010   6       Aa3      199779 - 201010
10:   199779 201012   3   A+           199779 - 201012
11:   199779 201112   2    A           199779 - 201112
12:   199779 201211  16    A           199779 - 201211
13:   199784 200501   5        A3 BBB- 199784 - 200501
14:   199784 200501   6 BBB+           199784 - 200501
15:   199784 200501   7        A3      199784 - 200501
16:   199784 200505   5            BB+ 199784 - 200505
17:   199784 200512  19  BB+           199784 - 200512
18:   199784 200601   5            BB- 199784 - 200601
19:   199784 200601  11       Ba2      199784 - 200601
20:   199784 200603  13   BB           199784 - 200603
```


```
Classes ‘data.table’ and 'data.frame':  20 obs. of  7 variables:
 $ issue_id: int  199779 199779 199779 199779 199779 199779 199779 199779 199779 199779 ...
 $ month   : int  200501 200501 200505 200605 200706 200805 200904 201004 201010 201012 ...
 $ day     : int  6 25 11 23 7 19 20 30 6 3 ...
 $ FR      : chr  "" "" "A" "A" ...
 $ MR      : chr  "" "Baa1" "" "" ...
 $ SPR     : chr  "A" "" "" "" ...
 $ superid : chr  "199779 - 200501" "199779 - 200501" "199779 - 200505" "199779 - 200605" ...
 - attr(*, ".internal.selfref")=<externalptr> 
```

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

На сегодняшний день я могу использовать только вот так:

```
list <- split(test, test$superid)

list <- lapply(list, function(x) {

   x$monthFR <- x[min(which(!is.na(x$FR))),"FR"]
   x$monthMR <- x[min(which(!is.na(x$MR))),"MR"]
   x$monthSPR <- x[min(which(!is.na(x$SPR))),"SPR"]
   x
})

result <- bind_rows(list)
```

Что дает мне следующий результат:

```
    issue_id  month day   FR   MR  SPR         superid monthFR monthMR monthSPR
 1:   199779 200501   6              A 199779 - 200501                        A
 2:   199779 200501  25      Baa1      199779 - 200501                        A
 3:   199779 200505  11    A           199779 - 200505       A                 
 4:   199779 200605  23    A           199779 - 200605       A                 
 5:   199779 200706   7    A           199779 - 200706       A                 
 6:   199779 200805  19    A           199779 - 200805       A                 
 7:   199779 200904  20   A+           199779 - 200904      A+                 
 8:   199779 201004  30   A+           199779 - 201004      A+                 
 9:   199779 201010   6       Aa3      199779 - 201010             Aa3         
10:   199779 201012   3   A+           199779 - 201012      A+                 
11:   199779 201112   2    A           199779 - 201112       A                 
12:   199779 201211  16    A           199779 - 201211       A                 
13:   199784 200501   5        A3 BBB- 199784 - 200501              A3     BBB-
14:   199784 200501   6 BBB+           199784 - 200501              A3     BBB-
15:   199784 200501   7        A3      199784 - 200501              A3     BBB-
16:   199784 200505   5            BB+ 199784 - 200505                      BB+
17:   199784 200512  19  BB+           199784 - 200512     BB+                 
18:   199784 200601   5            BB- 199784 - 200601                      BB-
19:   199784 200601  11       Ba2      199784 - 200601                      BB-
20:   199784 200603  13   BB           199784 - 200603      BB  

```

Как вы можете видеть, это не работает, поскольку в тех случаях, когда в один и тот же месяц были даны разные оценки (строки 1 и 13), мне всегда не хватает одного рейтинга.

Кроме того, этот код очень медленный для моего набора данных, который содержит 42 000 наблюдений.

Я знаю, что, возможно, есть более быстрое решение с использованием data.table или dplyr, но я не смог его найти.

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

```
            superid monthFR monthMR monthSPR
 1: 199779 - 200501            Baa1        A
 3: 199779 - 200505       A
 4: 199779 - 200605       A                    
 5: 199779 - 200706       A                 
 6: 199779 - 200805       A                 
 7: 199779 - 200904      A+     
 8: 199779 - 201004      A+                  
 9: 199779 - 201010             Aa3         
10: 199779 - 201012      A+                 
11: 199779 - 201112       A                 
12: 199779 - 201211       A                 
13: 199784 - 200501    BBB+      A3     BBB-
16: 199784 - 200505                      BB+
17: 199784 - 200512     BB+                 
18: 199784 - 200601                      BB-
20: 199784 - 200603      BB              

```   

Любая помощь будет принята с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...