在 data.table 和管道中正确使用 na.approx
Correct use of na.approx in data.table and pipe
我是 data.table
的新手,想尝试一下它是否能让我的分析速度更快。我主要使用 knitr
来编译 .rnw
文件(我倾向于每小时编译很多次,所以我希望它尽可能快)。
我在下面发布了一个示例,这绝不是与 data.table
和 data.frame
进行比较的问题。我想知道我下面的代码是否正确。
我基本上加入了两个 data.tables
,然后需要使用 na.approx
缺失的 NA
值进行线性近似。我使用了 R-Pubs 的 Introduction to data.table vignette from CRAN and JOINing data in R using data.table。
我在下面使用的代码导致我对 data.table
方法的最佳尝试花费了很长时间(一般来说,我也只添加了其他代码参考)。
此外,如果有人知道是否有一种方法可以将 na.approx()
传送到链中并且仍然具有 data.frame
的输出,我们将不胜感激。请注意 df_merged = as.data.frame(df_merged)
行,如果可能的话我想去掉它!
非常感谢任何输入,谢谢!
library(data.table)
library(zoo)
library(dplyr)
dt_function_test = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1E5, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
dt_merged = merge(dt_random[],
dt_na[],
all = TRUE)
dt_merged = dt_merged[, lapply(.SD,
na.approx),
by = vals]
}
df_function_test = function() {
set.seed(123)
# data.frame
df_random = data.frame(vals = runif(1E5, 0, 500))
df_na = data.frame(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
df_merged = full_join(df_random,
df_na) %>%
na.approx
df_merged = as.data.frame(df_merged)
}
print(system.time(dt_function_test()))
# user system elapsed
# 11.42 0.00 11.46
print(system.time(df_function_test()))
# Joining, by = "vals"
# user system elapsed
# 0.05 0.05 0.10
下面是一些使用 data.table
在 ref*
列上执行 zoo::na.approx
的可能实现(请注意,还使用了更大的数据集):
library(data.table)
library(zoo)
dt_function_test_0 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 0
merge(dt_random, dt_na, all=TRUE)[, lapply(.SD, na.approx)]
}
dt_function_test_1 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 1: using update by reference
merge(dt_random, dt_na, all = TRUE)[,
(cols) := lapply(.SD, na.approx), .SDcols=cols]
}
dt_function_test_2 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 2: using set
dt_merged <- merge(dt_random, dt_na, all = TRUE)
for (x in cols)
set(dt_merged, j=x, value=na.approx(dt_merged[[x]]))
dt_merged
}
定时输出:
> system.time(dt_function_test_0())
user system elapsed
5.44 1.90 6.96
> system.time(dt_function_test_1())
user system elapsed
3.55 1.30 4.41
> system.time(dt_function_test_2())
user system elapsed
3.78 1.19 4.52
我是 data.table
的新手,想尝试一下它是否能让我的分析速度更快。我主要使用 knitr
来编译 .rnw
文件(我倾向于每小时编译很多次,所以我希望它尽可能快)。
我在下面发布了一个示例,这绝不是与 data.table
和 data.frame
进行比较的问题。我想知道我下面的代码是否正确。
我基本上加入了两个 data.tables
,然后需要使用 na.approx
缺失的 NA
值进行线性近似。我使用了 R-Pubs 的 Introduction to data.table vignette from CRAN and JOINing data in R using data.table。
我在下面使用的代码导致我对 data.table
方法的最佳尝试花费了很长时间(一般来说,我也只添加了其他代码参考)。
此外,如果有人知道是否有一种方法可以将 na.approx()
传送到链中并且仍然具有 data.frame
的输出,我们将不胜感激。请注意 df_merged = as.data.frame(df_merged)
行,如果可能的话我想去掉它!
非常感谢任何输入,谢谢!
library(data.table)
library(zoo)
library(dplyr)
dt_function_test = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1E5, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
dt_merged = merge(dt_random[],
dt_na[],
all = TRUE)
dt_merged = dt_merged[, lapply(.SD,
na.approx),
by = vals]
}
df_function_test = function() {
set.seed(123)
# data.frame
df_random = data.frame(vals = runif(1E5, 0, 500))
df_na = data.frame(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
df_merged = full_join(df_random,
df_na) %>%
na.approx
df_merged = as.data.frame(df_merged)
}
print(system.time(dt_function_test()))
# user system elapsed
# 11.42 0.00 11.46
print(system.time(df_function_test()))
# Joining, by = "vals"
# user system elapsed
# 0.05 0.05 0.10
下面是一些使用 data.table
在 ref*
列上执行 zoo::na.approx
的可能实现(请注意,还使用了更大的数据集):
library(data.table)
library(zoo)
dt_function_test_0 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 0
merge(dt_random, dt_na, all=TRUE)[, lapply(.SD, na.approx)]
}
dt_function_test_1 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 1: using update by reference
merge(dt_random, dt_na, all = TRUE)[,
(cols) := lapply(.SD, na.approx), .SDcols=cols]
}
dt_function_test_2 = function() {
set.seed(123)
# data.table
dt_random = data.table(vals = runif(1e7, 0, 500))
dt_na = data.table(vals = c(0, 250, 500),
ref1 = c(0.33, 0.45, 0.78),
ref2 = c(0.12, 0.79, 1))
cols <- c("ref1", "ref2")
##Version 2: using set
dt_merged <- merge(dt_random, dt_na, all = TRUE)
for (x in cols)
set(dt_merged, j=x, value=na.approx(dt_merged[[x]]))
dt_merged
}
定时输出:
> system.time(dt_function_test_0())
user system elapsed
5.44 1.90 6.96
> system.time(dt_function_test_1())
user system elapsed
3.55 1.30 4.41
> system.time(dt_function_test_2())
user system elapsed
3.78 1.19 4.52