在大数据框架上优化 ifelse
Optimizing ifelse on a large data frame
我有一个数据框 df 如下所示:
A B C
1 2 3
2 5 6
3 8 9
下面的代码行添加了一个新列并相应地填充了数据。
df$Mean.Result1 <- ifelse(df[, "A"] > 0.05 & df[, "B"] > 0.05, "Equal", "")
我在 Splunk 中使用 R,在 中使用 R Splunk 无法识别上述格式。
这样做对吗:
df.$Mean.Result1 <- ifelse(df.$A > 0.05 & df$B > 0.05, "Equal", "")
这两段代码有何不同?会不会影响计算速度?我的实际数据集大约有 5 亿行和 400 列。
has been some discussion 关于 ifelse
不是速度是重要因素的代码的最佳选择。您可以改为尝试:
df$Mean.Result1 <- c("", "Equal")[(df$A > 0.05 & df$B > 0.05)+1]
要了解这里发生了什么,让我们分解命令。 df$A > 0.05 & df$B > 0.05
returns TRUE
如果 A
和 B
都超过 0.05,否则 FALSE
。因此,如果 A
和 B
都超过 0.05,则 (df$A > 0.05 & df$B > 0.05)+1
returns 2,否则为 1。这些用作向量 c("", "Equal")
中的指示,因此当两者都超过 0.05 时我们得到 "Equal"
,否则得到 ""
。
这是对具有 100 万行的数据框的比较:
# Build dataset and functions
set.seed(144)
big.df <- data.frame(A = runif(1000000), B = runif(1000000))
OP <- function(df) {
df$Mean.Result1 <- ifelse(df$A > 0.05 & df$B > 0.05, "Equal", "")
df
}
josilber <- function(df) {
df$Mean.Result1 <- c("", "Equal")[(df$A > 0.05 & df$B > 0.05)+1]
df
}
all.equal(OP(big.df), josilber(big.df))
# [1] TRUE
# Benchmark
library(microbenchmark)
microbenchmark(OP(big.df), josilber(big.df))
# Unit: milliseconds
# expr min lq mean median uq max neval
# OP(big.df) 299.6265 311.56167 352.26841 318.51825 348.09461 540.0971 100
# josilber(big.df) 40.4256 48.66967 60.72864 53.18471 59.72079 267.3886 100
矢量索引方法在中位运行时间中快了大约 6 倍。
我有一个数据框 df 如下所示:
A B C
1 2 3
2 5 6
3 8 9
下面的代码行添加了一个新列并相应地填充了数据。
df$Mean.Result1 <- ifelse(df[, "A"] > 0.05 & df[, "B"] > 0.05, "Equal", "")
我在 Splunk 中使用 R,在 中使用 R Splunk 无法识别上述格式。
这样做对吗:
df.$Mean.Result1 <- ifelse(df.$A > 0.05 & df$B > 0.05, "Equal", "")
这两段代码有何不同?会不会影响计算速度?我的实际数据集大约有 5 亿行和 400 列。
has been some discussion 关于 ifelse
不是速度是重要因素的代码的最佳选择。您可以改为尝试:
df$Mean.Result1 <- c("", "Equal")[(df$A > 0.05 & df$B > 0.05)+1]
要了解这里发生了什么,让我们分解命令。 df$A > 0.05 & df$B > 0.05
returns TRUE
如果 A
和 B
都超过 0.05,否则 FALSE
。因此,如果 A
和 B
都超过 0.05,则 (df$A > 0.05 & df$B > 0.05)+1
returns 2,否则为 1。这些用作向量 c("", "Equal")
中的指示,因此当两者都超过 0.05 时我们得到 "Equal"
,否则得到 ""
。
这是对具有 100 万行的数据框的比较:
# Build dataset and functions
set.seed(144)
big.df <- data.frame(A = runif(1000000), B = runif(1000000))
OP <- function(df) {
df$Mean.Result1 <- ifelse(df$A > 0.05 & df$B > 0.05, "Equal", "")
df
}
josilber <- function(df) {
df$Mean.Result1 <- c("", "Equal")[(df$A > 0.05 & df$B > 0.05)+1]
df
}
all.equal(OP(big.df), josilber(big.df))
# [1] TRUE
# Benchmark
library(microbenchmark)
microbenchmark(OP(big.df), josilber(big.df))
# Unit: milliseconds
# expr min lq mean median uq max neval
# OP(big.df) 299.6265 311.56167 352.26841 318.51825 348.09461 540.0971 100
# josilber(big.df) 40.4256 48.66967 60.72864 53.18471 59.72079 267.3886 100
矢量索引方法在中位运行时间中快了大约 6 倍。