r-查找数据帧间隔内的最大值



我有一个数据帧,每5秒有一个x/y值,每秒钟有一个深度值(时间列(。有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    

我想计算非NA的x/y值之间的最大深度,并将其添加到起始x/y值行中的新列中。所以第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值,就会重复此操作。

您可以将avecumsum!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

使用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

也许你可以像下面的一样尝试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"))

这里有另一个使用data.table:的选项

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