Сумма последовательных одинаковых значений - PullRequest
0 голосов
/ 25 апреля 2018
    slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1
     0.4    0

Я хочу знать сумму наклона каждого события, где 1 и, если доступно, последовательно 1 происходит.Так что я получаю вывод, как это:

slope   term    sum_slope
0.5      1        1.3
0.8      1        1.3
0.3      0        NA
0.25     0        NA
0.18     0        NA
0.4      0        NA
1.2      1       5.47
3.6      1       5.47
0.67     1       5.47
0.3      0        NA
0.8      1       0.8
0.2      0        NA

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Вот опция, использующая base R.Создайте группирующую переменную, используя rle ('grp'), затем с помощью ave, сгруппированные по 'grp', получите sum для 'slope' после преобразования тех значений, которые соответствуют 'term' 0, в NA

grp <- inverse.rle(within.list(rle(df1$term), values <- seq_along(values)))
df1$sum_slope <-  with(df1, ave(slope * (NA^!term), grp, FUN = sum))
df1$sum_slope
#[1] 1.30 1.30   NA   NA   NA   NA 5.47 5.47 5.47   NA 0.80   NA
0 голосов
/ 25 апреля 2018

1) При этом используется rleid из data.table для создания переменной группировки и базы R для остальных. ave вычисляет сумму каждой группы и ifelse NA из 0 групп.

library(data.table)
transform(DF, sum_slope = ave(slope, rleid(term), FUN = sum) * ifelse(term, 1, NA))

дает:

   slope term sum_slope
1   0.50    1      1.30
2   0.80    1      1.30
3   0.30    0        NA
4   0.25    0        NA
5   0.18    0        NA
6   0.40    0        NA
7   1.20    1      5.47
8   3.60    1      5.47
9   0.67    1      5.47
10  0.30    0        NA
11  0.80    1      0.80
12  0.40    0        NA

2) В этом варианте вышеизложенного используется только базовый R. Он заменяет rleid базовым выражением cumsum(...), которое делает то же самое.

transform(DF, sum_slope = 
  ave(slope, cumsum(c(FALSE, diff(term) != 0)), FUN = sum) * ifelse(term, 1, NA))

Примечание

Ввод в воспроизводимом виде:

Lines <- "
 slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1
     0.4    0"
DF <- read.table(text = Lines, header = TRUE)
0 голосов
/ 25 апреля 2018

Это не точно , что вы хотите, но вы можете использовать data.table::rleid для группировки ваших данных - rleid - это версия data.table * rle

Данные

df <- read.table(text="slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1", header=TRUE)

Решение

library(data.table)
dt <- setDT(df)
dt[, sum:=sum(slope)*max(term), by=rleid(term)]
dt

    # slope term  sum
 # 1:  0.50    1 1.30
 # 2:  0.80    1 1.30
 # 3:  0.30    0 0.00
 # 4:  0.25    0 0.00
 # 5:  0.18    0 0.00
 # 6:  0.40    0 0.00
 # 7:  1.20    1 5.47
 # 8:  3.60    1 5.47
 # 9:  0.67    1 5.47
# 10:  0.30    0 0.00
# 11:  0.80    1 0.80
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...