Найти максимальное значение в интервале фрейма данных - PullRequest
3 голосов
/ 21 апреля 2020

У меня есть фрейм данных, который имеет значения x / y каждые 5 секунд, со значением глубины каждую секунду (столбец времени). Нет глубины, где есть значение x / y.

x <- c("1430934", NA, NA, NA, NA, "1430939")
y <- c("4943206", NA, NA, NA, NA, "4943210")
time <- c(1:6)
depth <- c(NA, 10, 19, 84, 65, NA)
data <- data.frame(x, y, time, depth)
data 
     x       y      time depth
1 1430934 4943206    1    NA     
2    NA    NA        2    10     
3    NA    NA        3    19     
4    NA    NA        4    84     
5    NA    NA        5    65   
6 1430939 4943210    6    NA    

Я хотел бы рассчитать максимальную глубину между значениями x / y, которые не являются NA, и добавить это в новый столбец в строке из начальных значений х / у. Так что максимальная глубина рядов 2-5. Пример желаемого вывода.

    x       y       time depth newvar
1 1430934 4943206    1    NA     84
2    NA    NA        2    10     NA
3    NA    NA        3    19     NA
4    NA    NA        4    84     NA
5    NA    NA        5    65     NA
6 1430939 4943210    6    NA     NA

Это должно повторяться всякий раз, когда присутствует новое значение x / y.

Ответы [ 4 ]

1 голос
/ 21 апреля 2020

Вы можете использовать ave и cumsum с !is.na, чтобы получить группы для ave, например:

data$newvar <- ave(data$depth, cumsum(!is.na(data$x)), FUN=
 function(x) if(all(is.na(x))) NA else {
  c(max(x, na.rm=TRUE), rep(NA, length(x)-1))})
data
#        x       y time depth newvar
#1 1430934 4943206    1    NA     84
#2    <NA>    <NA>    2    10     NA
#3    <NA>    <NA>    3    19     NA
#4    <NA>    <NA>    4    84     NA
#5    <NA>    <NA>    5    65     NA
#6 1430939 4943210    6    NA     NA
1 голос
/ 21 апреля 2020

Используя dplyr, мы можем создать группы из каждых 5 строк и обновить первую строку в группе как значение max в группе, игнорируя значения NA.

library(dplyr)

df %>%
  group_by(grp = ceiling(time/5)) %>%
  mutate(depth = ifelse(row_number() == 1, max(depth, na.rm = TRUE), NA))

В базе R мы можем использовать tapply:

inds <- seq(1, nrow(df), 5)
df$depth[inds] <- tapply(df$depth, ceiling(df$time/5), max, na.rm = TRUE)
df$depth[-inds] <- NA
1 голос
/ 21 апреля 2020

Может быть, вы можете попробовать ave, как показано ниже

df <- within(df,
             newvar <- ave(depth,
                           ceiling(time/5),
                           FUN = function(x) ifelse(length(x)>1&is.na(x),max(na.omit(x)),NA)))

, чтобы

> df
        x       y time depth newvar
1 1430934 4943206    1    NA     84
2      NA      NA    2    10     NA
3      NA      NA    3    19     NA
4      NA      NA    4    84     NA
5      NA      NA    5    65     NA
6 1430939 4943210    6    NA     NA

ДАННЫЕ

df <- structure(list(x = c(1430934L, NA, NA, NA, NA, 1430939L), y = c(4943206L, 
NA, NA, NA, NA, 4943210L), time = 1:6, depth = c(NA, 10L, 19L, 
84L, 65L, NA)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6"))
0 голосов
/ 22 апреля 2020

Вот еще один вариант использования data.table:

library(data.table)
setDT(data)[, newvar := replace(frollapply(depth, 5L, max, na.rm=TRUE, align="left"),
    seq(.N) %% 5L != 1L, NA_integer_)]
...