Как применить функцию для каждой строки столбца в таблице данных с другими строками в качестве входных данных? - PullRequest
0 голосов
/ 18 января 2019

Для каждой строки столбца «Ответ» я хотел бы проверить, имеют ли 5 ​​строк ниже его значения «Ответ» (т. Е. Не имеют NA), и если да, то я хотел бы рассчитать среднее и стандартное отклонение из этих 5 строк ниже. Если какая-либо строка в этих 5 строках ниже имеет отсутствующее значение «Response» (то есть NA), тогда конечный результат должен быть «NA» (поскольку я хочу, чтобы средние значения и stdev вычислялись для n = 5 баллов / значений ).

Пример Input.data выглядит следующим образом:

 Response     
        NA               
         1                 
         2                 
         3                
        NA        
         1         
         1         
         2         
         3         
         4         
         5    

Вот код, который я пробовал, который не дал правильного решения:

Input.data$count.lag <- rollapplyr(Input.data[,c("Response")],list(-(4:0)),length, fill=NA)

Input.data$stdev <- ifelse(Input.data$count.lag <5, "NA", 
                            rollapplyr(Input.data[,c("Response")],list(-(4:0)),sd,fill=NA))
Input.data$mean <- ifelse(Input.data$count.lag <5, "NA", 
                           rollapplyr(Input.data[,c("Response")],list(-(4:0)),mean,fill=NA))

это дало следующее, что было не тем, что я хочу:

 Response count.lag     stdev mean
       NA        NA        NA   NA
        1        NA        NA   NA
        2        NA        NA   NA
        3        NA        NA   NA
       NA         5        NA   NA
        1         5        NA   NA
        1         5        NA   NA
        2         5        NA   NA
        3         5        NA   NA
        4         5  1.303840  2.2
        5         5  1.581139  3.0

Вот как должен был быть вывод:

Response count.lag      stdev  mean
     NA         4        NA    NA
      1         4        NA    NA
      2         4        NA    NA
      3         4        NA    NA
     NA         5   1.303840   2.2
      1         5   1.581139   3.0
      1         5   1.581139   4.0
      2         5   1.581139   5.0
      3         5   1.581139   6.0
      4         5   1.581139   7.0
      5         5   1.581139   8.0

Может кто-нибудь предложить, где ошибки и / или альтернативное решение, которое работает? Спасибо!

1 Ответ

0 голосов
/ 18 января 2019

Возможный подход:

Input[, c("count.lag","stdev","mean") := 
    transpose(lapply(1L:.N, function(n) {
        x <- Response[(n+1L):min(n+5L, .N)]
        c(sum(!is.na(x)), sd(x), mean(x))
    }))]

выход:

    Response count.lag     stdev mean
 1:       NA         4        NA   NA
 2:        1         4        NA   NA
 3:        2         4        NA   NA
 4:        3         4        NA   NA
 5:       NA         5 1.3038405  2.2
 6:        1         5 1.5811388  3.0
 7:        1         5 1.5811388  4.0
 8:        2         5 1.5811388  5.0
 9:        3         5 1.5811388  6.0
10:        4         5 1.5811388  7.0
11:        5         5 1.5811388  8.0
12:        6         4 1.2909944  8.5
13:        7         3 1.0000000  9.0
14:        8         2 0.7071068  9.5
15:        9         1        NA 10.0
16:       10         1        NA   NA

данные:

Input <- fread("Response     
NA               
1                 
2                 
3                
NA        
1         
1         
2         
3         
4         
5
6
7
8
9
10")

edit: или согласно предложению MichaelChirico, используя shift. Конечные значения различны и зависят от того, как OP хочет обрабатывать конечные значения.

#requires data.table version >= 1.12.0 to use negative shifts (else use type='lag' with positive integers
Input[, c("count.lag", "stdev", "mean") := 
    .SD[, shift(Response, -1L:-5L)][, 
        .(apply(.SD, 1L, function(x) sum(!is.na(x))), 
            apply(.SD, 1L, sd), 
            apply(.SD, 1L, mean))]
]

выход:

    Response count.lag    stdev mean
 1:       NA         4       NA   NA
 2:        1         4       NA   NA
 3:        2         4       NA   NA
 4:        3         4       NA   NA
 5:       NA         5 1.303840  2.2
 6:        1         5 1.581139  3.0
 7:        1         5 1.581139  4.0
 8:        2         5 1.581139  5.0
 9:        3         5 1.581139  6.0
10:        4         5 1.581139  7.0
11:        5         5 1.581139  8.0
12:        6         4       NA   NA
13:        7         3       NA   NA
14:        8         2       NA   NA
15:        9         1       NA   NA
16:       10         0       NA   NA
...