R 如何计算从多个连续列中选择最大范围值的变量

R 如何计算从多个连续列中选择最大范围值的变量,r,dplyr,data.table,R,Dplyr,Data.table,我有一个数据框df,它总结了几个月内不同深度(5米T5、15米T15、25米T25和35米T35)的每小时水温。例如: df<- data.frame(DateTime=c("2018-08-09 08:00:00","2018-08-09 09:00:00","2018-08-09 10:00:00","2018-08-09 11:00:00","2018-08-09 12:00:00","2018-08-09 13:00:00"), T5=c(14.5,

我有一个数据框
df
,它总结了几个月内不同深度(5米
T5
、15米
T15
、25米
T25
和35米
T35
)的每小时水温。例如:

df<- data.frame(DateTime=c("2018-08-09 08:00:00","2018-08-09 09:00:00","2018-08-09 10:00:00","2018-08-09 11:00:00","2018-08-09 12:00:00","2018-08-09 13:00:00"),
                T5=c(14.5,18.4,21.3,27.8,16.5,21.5),
                T15=c(13.8,16.3,16.2,17.8,19.3,20.1),
                T25=c(16.0,17.2,18.3,15.9,21.4,17.3),
                T35=c(16.1,15.7,16.2,15.6,17.0,16.3))

df$DateTime<- as.POSIXct(df$DateTime, formtat="%Y-%m-%d %H:%M:%S",tz="UTC")

df

             DateTime   T5  T15  T25  T35
1 2018-08-09 08:00:00 14.5 13.8 16.0 16.1
2 2018-08-09 09:00:00 18.4 16.3 17.2 15.7
3 2018-08-09 10:00:00 21.3 16.2 18.3 16.2
4 2018-08-09 11:00:00 27.8 17.8 15.9 15.6
5 2018-08-09 12:00:00 16.5 19.3 21.4 17.0
6 2018-08-09 13:00:00 21.5 20.1 17.3 16.3
有没有简单快速的方法来计算所有的?我对使用包
data.table
特别感兴趣,尽管任何方法都可以


提前感谢

在base R中,我们可以使用
apply
行方式来计算差异

df[c("MWTCC", "WTC10","WTC20", "WTC30")] <- t(apply(df[-1], 1, function(x) {
     vals <- abs(diff(x))
     c(max(vals), vals)
}))

df
#             DateTime   T5  T15  T25  T35 MWTCC WTC10 WTC20 WTC30
#1 2018-08-09 08:00:00 14.5 13.8 16.0 16.1   2.2   0.7   2.2   0.1
#2 2018-08-09 09:00:00 18.4 16.3 17.2 15.7   2.1   2.1   0.9   1.5
#3 2018-08-09 10:00:00 21.3 16.2 18.3 16.2   5.1   5.1   2.1   2.1
#4 2018-08-09 11:00:00 27.8 17.8 15.9 15.6  10.0  10.0   1.9   0.3
#5 2018-08-09 12:00:00 16.5 19.3 21.4 17.0   4.4   2.8   2.1   4.4
#6 2018-08-09 13:00:00 21.5 20.1 17.3 16.3   2.8   1.4   2.8   1.0

df[c(“MWTCC”、“WTC10”、“WTC20”、“WTC30”)]另一个性能相当的基本解决方案:

#define columns to help automate
cols <- grep('^T', names(df))
Ts <- as.integer(substring(names(df)[cols], 2))
new_cols <- paste0('WTC', Ts[-1] - Ts[1])

# do the column difference calculation
df[, new_cols] <- abs(df[, cols[-1]] - df[, cols[-length(cols)]])
df[['MWTCC']] <- do.call(pmax, df[, new_cols])

df
#定义列以帮助自动化
科尔斯
#define columns to help automate
cols <- grep('^T', names(df))
Ts <- as.integer(substring(names(df)[cols], 2))
new_cols <- paste0('WTC', Ts[-1] - Ts[1])

# do the column difference calculation
df[, new_cols] <- abs(df[, cols[-1]] - df[, cols[-length(cols)]])
df[['MWTCC']] <- do.call(pmax, df[, new_cols])

df
library(data.table)
dt <- as.data.table(df)

dt[, (new_cols) := abs(dt[, .SD, .SDcols = cols[-1]] - dt[, .SD, .SDcols = cols[-length(cols)]])]
dt[, MWTCC := do.call(pmax, .SD)]

# or perhaps this - I assume tidyverse would use purrr::map() in a similar fashion

dt[, (new_cols) := lapply(seq_len(length(cols) - 1),
                          function(i) {
                            abs(dt[[cols[i+1]]] - dt[[cols[i]]])
                          }
                          )]
dt[, MWTCC := do.call(pmax, .SD)]
set.seed(0L)
nr <- 1e6
df <- data.frame(T5=rnorm(nr), T15=rnorm(nr), T25=rnorm(nr), T35=rnorm(nr))
cols <- c("T5", "T15", "T25", "T35")
cols <- grep('^T', names(df))
Ts <- as.integer(substring(names(df)[cols], 2))
new_cols <- paste0('WTC', Ts[-1] - Ts[1])

library(data.table)
dt <- as.data.table(df)


mtd0 <- function() {
    df[c("MWTCC", new_cols)] <- t(apply(df[cols], 1, function(x) {
        vals <- abs(diff(x))
        c(max(vals), vals)
    }))
    df
}

mtd2 <- function() {
    # do the column difference calculation
    df[, new_cols] <- abs(df[, cols[-1]] - df[, cols[-length(cols)]])
    df[['MWTCC']] <- do.call(pmax, df[, new_cols])

    df[, c(names(df)[cols], 'MWTCC', new_cols)]
}

mtd_DT <- function() {

    dt[, (new_cols) := abs(dt[, .SD, .SDcols = cols[-1]] - dt[, .SD, .SDcols = cols[-length(cols)]])]
    dt[, MWTCC := do.call(pmax, .SD)]

    # or perhaps this - I assume tidyverse would use purrr::map() in a similar fashion

    dt[, (new_cols) := lapply(seq_len(length(cols) - 1),
        function(i) {
            abs(dt[[cols[i+1]]] - dt[[cols[i]]])
        }
    )]
    dt[, MWTCC := do.call(pmax, .SD)]   
}

bench::mark(mtd0(), mtd2(), mtd_DT(), check=FALSE)
# A tibble: 3 x 13
  expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result                   memory                time     gc              
  <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> <list>                   <list>                <list>   <list>          
1 mtd0()        14.1s    14.1s    0.0707   405.8MB     4.39     1    62      14.1s <df[,8] [1,000,000 x 8]> <df[,3] [46,873 x 3]> <bch:tm> <tibble [1 x 3]>
2 mtd2()       30.7ms   42.9ms   16.6       57.2MB     3.69     9     2    542.5ms <df[,8] [1,000,000 x 8]> <df[,3] [8 x 3]>      <bch:tm> <tibble [9 x 3]>
3 mtd_DT()    170.4ms  172.6ms    4.85     215.7MB     6.47     3     4      618ms <df[,8] [1,000,000 x 8]> <df[,3] [588 x 3]>    <bch:tm> <tibble [3 x 3]>