我想更改data.table而不是dplyrin dplyr::summarize(dplyr::across(ends_with("PV"), median),.groups = 'drop')。另外,我想知道您是否認為處理時間data.table比 by快dplyr?
library(dplyr)
library(tidyr)
library(lubridate)
#database
df1 <- data.frame( Id = rep(1:5, length=100000),
date1 = as.Date( "2021-12-01"),
date2= rep(seq( as.Date("2021-01-01"), length.out=50000, by=1), each = 2),
Category = rep(c("ABC", "EFG"), length.out = 100000),
Week = rep(c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday", "Sunday"), length.out = 100000),
DR1 = sample( 200:250, 100000, repl=TRUE),
setNames( replicate(365, { sample(0:100000, 100000)}, simplify=FALSE),
paste0("DRM", formatC(1:365, width = 2, format = "d", flag = "0"))))
subsetDRM<- df1 %>% select(starts_with("DRM"))
DR1_subsetDRM<-cbind (df1, setNames(df1$DR1 - subsetDRM, paste0(names(subsetDRM), "_PV")))
subset_PV<-select(DR1_subsetDRM,Id, date2,Week, Category, DR1, ends_with("PV"))
result_median<-subset_PV %>%
group_by(Id,Category,Week) %>%
dplyr::summarize(dplyr::across(ends_with("PV"), median),.groups = 'drop')
uj5u.com熱心網友回復:
我認為 akrun 的回答提供了一個很好的運算式轉換。但是,如果您不需要復制這些步驟,則可以嘗試以下操作:
library(data.table)
dt1 <- as.data.table(df1)
cols <- grep("^DRM", colnames(dt1), value = TRUE)
dt1_results_median <-
dt1[, (paste0(cols, "_PV")) := DR1 - .SD, .SDcols = cols
][, lapply(.SD, median), by = .(Id, Category, Week), .SDcols = paste0(cols, "_PV") ]
相對表現,兩個答案都有小幅提升(33-41%):
bench::mark(OP = {...}, akrun = {...}, r2evans = {...}, check = FALSE, iterations = 10)
# Warning: Some expressions had a GC in every iteration; so filtering is disabled.
# # 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 OP 1.61s 1.72s 0.583 2.01GB 3.15 10 54 17.2s <NULL> <Rprofmem~ <benc~ <tibbl~
# 2 akrun 1.24s 1.29s 0.773 2.29GB 1.47 10 19 12.9s <NULL> <Rprofmem~ <benc~ <tibbl~
# 3 r2evans 1.19s 1.21s 0.823 1.88GB 1.65 10 20 12.2s <NULL> <Rprofmem~ <benc~ <tibbl~
我認識到 akrun 的回答可能更多地是作為一個教學時刻,從 R 的一種方言翻譯成另一種方言,所以速度差異是“沒有實際意義的”。在這個比較運行時,我認為使用更具可讀性和可理解性的代碼更為重要,這使得它更易于維護,并且在您需要更改方法時更容易進行故障排除。
uj5u.com熱心網友回復:
如果我們想要直接翻譯為data.table,也許下面的代碼會有所幫助
library(data.table)
# convert data.frame to data.table - setDT
setDT(df1)
# subset the columns of DRM to create subsetDRM
subsetDRM <- df1[, .SD, .SDcols = patterns("^DRM")]
# subtract the subsetDRM from df1
DR1_subsetDRM <- cbind(df1, setNames(df1$DR1 -
subsetDRM, paste0(names(subsetDRM), "_PV")))
pv_nm1 <- names(DR1_subsetDRM)[endsWith(names(DR1_subsetDRM), "PV")]
nm1 <- c("Id", "date2", "Week", "Category", "DR1", pv_nm1)
# create the subset_PV
subset_PV <- DR1_subsetDRM[, .SD, .SDcols = nm1]
# do a group by median
result_median <- subset_PV[, lapply(.SD, median),
by = .(Id, Category, Week), .SDcols = pv_nm1]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/418392.html
標籤:
