Как суммировать значения вектора на основе монотонности другого вектора (увеличение / уменьшение)

#r

#r

Вопрос:

У меня есть этот набор данных

 x<-c(52,52,51,51,51,51,50,50,50,49,49,49,49,48,48,50,60,70,80,90,100,100,100,100,100,100,99,98,98,95,94,80,70,60,70,80,90,100,100,100,90,80,70,60,50,40,30,20,10,70,90,10)
y<-c(rep(c(30),times(51)))
y<-c(NA,y)
x
y
data<-cbind(x,y)
data<-data.frame(data)
data
 

Все, что я хочу, это суммировать переменную y, когда x увеличивается при уменьшении, и наоборот

Ну, я попробовал это

 d <- c(TRUE, diff(data$x) <= 0)
f <- cumsum(abs(c(0, diff(d))))
tapply(data$y, f, sum, na.rm = TRUE)
unname(tapply(data$y, f, sum, na.rm = TRUE))
 

Что дает мне это

 [1] 420 180 390 120 330  60  30
 

Но проблема в том, что я хочу, чтобы он учитывался при увеличении до максимального значения, такого как ….,90,100,100, Он останавливается на первом значении 100, в то время как я хочу, чтобы он продолжался при всех значениях, пока не достигнет более низкого.

Результат, который я хочу, должен выглядеть так:

 [1] 420 330 270 180 270 60 30
 

Комментарии:

1. times(51) Должно быть times=51 ?

2. Нет, он реплицируется 30 51 раз, это одно и то же.

3. Error in times(51) : could not find function "times" . Вы используете неосновные пакеты R, или я действительно не понимаю, почему ваш пример кода не работает?

4. Для наглядности rep(30, times=51) повторяется 30 (51 раз).

5. Я запускаю точно такой же код, но вместо этого он выводит мне это [1] 30 390 330 240 180 270 60 30 По какой-то причине первый разделен

Ответ №1:

Ваши данные.

 x<-c(52,52,51,51,51,51,50,50,50,49,49,49,49,48,48,50,60,70,80,90,100,100,100,100,100,100,99,98,98,95,94,80,70,60,70,80,90,100,100,100,90,80,70,60,50,40,30,20,10,70,90,10)
y<-c(rep(c(30),times=51))
y<-c(NA,y)
data <- data.frame(x, y)
 
 d <- c(0, diff(data$x))
d[d==0] <- NA
d <- zoo::na.locf(zoo::na.locf(d, na.rm = FALSE), na.rm = FALSE, fromLast = TRUE)
f <- cumsum(abs(c(0, diff(d <= 0))))
tapply(data$y, f, sum, na.rm = TRUE)
#   0   1   2   3   4   5   6 
# 420 330 240 180 270  60  30