Обновить последний элемент в группе .SD на основе других элементов - PullRequest
0 голосов
/ 22 марта 2020

У меня есть набор данных dt в формате data.table, который выглядит как

  type id val

1 m     1   5
2 m     1   3
3 m     1  NA
3 e     2   7
4 e     3   7
5 m     4   4
6 m     4   2
7 m     4  NA

Я хочу заменить val последней записи (в моем примере NA) каждой группы на id типа m с суммой val других записей группы. То есть я хочу получить такой набор данных:

  type id val

1 m     1   5
2 m     1   3
3 m     1   8
3 e     2   7
4 e     3   7
5 m     4   4
6 m     4   2
7 m     4   6

В настоящее время я пытаюсь обернуть голову вокруг функций data.table, в частности .SD, и хочу решить проблему с помощью этих инструментов.

До сих пор я выяснил, что dt[type=="m",.SD[.N],.SDcols="val",by=id] дает мне доступ к соответствующим элементам, а dt[type=="m", lapply(.SD[1:.N-1]),.SDcols="val",by=id] дает мне правильную сумму. Однако я не могу соединить их вместе.

Любая помощь приветствуется.

Ответы [ 3 ]

1 голос
/ 22 марта 2020

Мы можем использовать na.aggregate

library(zoo)
library(data.table)
setDT(dt)[type == 'm', val := na.aggregate(val,  FUN = sum), id]
dt
#   type id val
#1:    m  1   5
#2:    m  1   3
#3:    m  1   8
#4:    e  2   7
#5:    e  3   7
#6:    m  4   4
#7:    m  4   2
#8:    m  4   6
0 голосов
/ 22 марта 2020

Другой вариант:

library(data.table)

setDT(dt)[type == 'm', val := c(val[-.N], sum(val, na.rm = TRUE)), by = id]

Выход:

   type id val
1:    m  1   5
2:    m  1   3
3:    m  1   8
4:    e  2   7
5:    e  3   7
6:    m  4   4
7:    m  4   2
8:    m  4   6
0 голосов
/ 22 марта 2020

Мы можем использовать replace:

library(data.table)

dt[type == "m", val := replace(val, .N, sum(val, na.rm = TRUE)), id]
dt

#   type id val
#1:    m  1   5
#2:    m  1   3
#3:    m  1   8
#4:    e  2   7
#5:    e  3   7
#6:    m  4   4
#7:    m  4   2
#8:    m  4   6
...