【发布时间】:2018-02-21 00:05:19
【问题描述】:
考虑以下基准(Windows 机器上的 R 3.4.1):
library(rbenchmark)
mtx <- matrix(runif(1e8), ncol = 100)
df <- as.data.frame(mtx)
colnames(mtx) <- colnames(df) <- paste0("V", 1:100)
benchmark(
mtx[5000:7000, 80],
mtx[5000:7000, "V80"],
mtx[, "V80"][5000:7000],
mtx[, "V80", drop = FALSE][5000:7000, ],
mtx[5000:7000, , drop = FALSE][, "V80"],
#mtx$V80[5000:7000], # does not apply
replications = 5000
)
## test replications elapsed relative user.self sys.self user.child sys.child
## 4 mtx[, "V80", drop = FALSE][5000:7000, ] 5000 64.71 588.273 47.44 16.61 NA NA
## 3 mtx[, "V80"][5000:7000] 5000 72.15 655.909 52.90 18.18 NA NA
## 2 mtx[5000:7000, "V80"] 5000 0.11 1.000 0.11 0.00 NA NA
## 5 mtx[5000:7000, , drop = FALSE][, "V80"] 5000 7.47 67.909 5.89 1.47 NA NA
## 1 mtx[5000:7000, 80] 5000 0.13 1.182 0.12 0.00 NA NA
benchmark(
df[5000:7000, 80],
df[5000:7000, "V80"],
df[, "V80"][5000:7000],
df[, "V80", drop = FALSE][5000:7000, ],
df[5000:7000, , drop = FALSE][, "V80"],
df$V80[5000:7000],
replications = 5000
)
## test replications elapsed relative user.self sys.self user.child sys.child
## 6 df$V80[5000:7000] 5000 0.13 1.000 0.12 0.00 NA NA
## 4 df[, "V80", drop = FALSE][5000:7000, ] 5000 0.33 2.538 0.33 0.00 NA NA
## 3 df[, "V80"][5000:7000] 5000 0.17 1.308 0.17 0.00 NA NA
## 2 df[5000:7000, "V80"] 5000 0.15 1.154 0.16 0.00 NA NA
## 5 df[5000:7000, , drop = FALSE][, "V80"] 5000 13.63 104.846 12.91 0.39 NA NA
## 1 df[5000:7000, 80] 5000 0.19 1.462 0.17 0.00 NA NA
时差非常显着。这是为什么?什么是推荐的子集化方式,为什么?鉴于基准,矩阵的mtx[i, colname] 方式和data.frame 的df$colname[i] (但似乎没有太大区别)似乎是最省时的,但是有什么一般原因我们应该更喜欢任何方法有哪些?
【问题讨论】:
-
并不总是建议对 data.frame 进行 $-extraction。它仅供交互使用。您可以添加
df[["V80"]]和df[[80]]提取方法。 -
只使用对您的特定矩阵/data.frame 最快的那个(假设子设置的速度甚至是代码的阻塞部分)。通常最好做一个子集操作
[],而不是两个[][]。您有不同的选项,因此您可以选择哪一个更具可读性或使您的代码更易于理解。