计算行最大值

Calculate row-wise maximum

我想创建一个新列,它等于该行所有列的最大值。

这是一个例子:

library(data.table)
data <- data.table(head(iris))
data[ , Species := NULL]
data

   Sepal.Length Sepal.Width Petal.Length Petal.Width
1:          5.1         3.5          1.4         0.2
2:          4.9         3.0          1.4         0.2
3:          4.7         3.2          1.3         0.2
4:          4.6         3.1          1.5         0.2
5:          5.0         3.6          1.4         0.2
6:          5.4         3.9          1.7         0.4

我真的不能在这里使用 max 函数,因为它会找到所有列的最大值,例如 data[, max_value := max(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)]。我想要的是这样的:

   Sepal.Length Sepal.Width Petal.Length Petal.Width max_value
1:          5.1         3.5          1.4         0.2       5.1
2:          4.9         3.0          1.4         0.2       4.9
3:          4.7         3.2          1.3         0.2       4.7
4:          4.6         3.1          1.5         0.2       4.6
5:          5.0         3.6          1.4         0.2       5.0
6:          5.4         3.9          1.7         0.4       5.4

我不保证它的速度,但这至少避免了对矩阵的强制转换:

data[,mymax:=do.call(pmax,.SD)]

使用 dplyr 你可以:

library(dplyr)
setDF(data) %>% 
  rowwise() %>% 
  mutate(max = max(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width))

#Source: local data frame [10 x 5]
#Groups: <by row>
#
#   Sepal.Length Sepal.Width Petal.Length Petal.Width max
#1           5.1         3.5          1.4         0.2 5.1
#2           4.9         3.0          1.4         0.2 4.9
#3           4.7         3.2          1.3         0.2 4.7
#4           4.6         3.1          1.5         0.2 4.6
#5           5.0         3.6          1.4         0.2 5.0
#6           5.4         3.9          1.7         0.4 5.4

或者按照@akrun 的建议:

setDF(data) %>% mutate(max=pmax(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width))

rowwise() 方法快得多:

n <- 10e6; nc <- 4; DT <- data.table(replicate(nc,rnorm(n))) 

mbm <- microbenchmark(
  steven = DT %>% rowwise() %>% mutate(V5 = max(V1, V2, V3, V4)),
  frank = DT[,c(.SD,list(do.call(pmax,.SD)))], 
  akrun = DT %>% mutate(V5 = pmax(V1, V2, V3, V4)), times = 25, unit = "relative")

#Unit: relative
#   expr      min        lq      mean   median        uq       max neval cld
# steven 17.93647 18.024734 17.535764 17.42948 17.484920 16.446384    25   b
#  frank  1.00000  1.000000  1.000000  1.00000  1.000000  1.000000    25  a 
#  akrun  1.00220  1.002281  1.013604  1.00240  1.003089  1.001262    25  a 

按行使用 by=1:nrow(data) 到 "group"(这使每一行成为自己的组):

data[, max_value:=max(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width), by=1:nrow(data)]

data
   Sepal.Length Sepal.Width Petal.Length Petal.Width max_value
1:          5.1         3.5          1.4         0.2       5.1
2:          4.9         3.0          1.4         0.2       4.9
3:          4.7         3.2          1.3         0.2       4.7
4:          4.6         3.1          1.5         0.2       4.6
5:          5.0         3.6          1.4         0.2       5.0
6:          5.4         3.9          1.7         0.4       5.4