這是一個評論有點太長了,所以一個單獨的答案:
首先,我提到爲@ R,S註釋的get()
功能。回答:
data.select.dt.V1 <- function(dset, seg.var, value){
if(!data.table::is.data.table(dset)) dset <- data.table::as.data.table(dset) # To convert only if needed
dset[get(seg.var) == value,]
}
data.select.dt.V1(iris, 'Species', 'setosa')
然後更data.table
功能,在這裏你可以通過第二個參數是一個表達式(當然,在data.table
方式),而不是一個字符串:
data.select.dt.V2 <- function(dset, seg.var, value){
if(!data.table::is.data.table(dset)) dset <- data.table::as.data.table(dset) # To convert only if needed
sv <- substitute(seg.var)
dset[eval(sv) == value,]
}
data.select.dt.V2(iris, Species, 'setosa')
編輯:功能簡化和轉換測試(感謝@David Arenburg評論)。
第二編輯:基準測試上述兩種功能與@大衛Arenburg對515 MB data.table
和data.frame
一個(有和沒有is.data.table
檢查,V3
和V4
分別地):
data.select.dt.V3 <- function(dset, seg.var, value) data.table::as.data.table(dset)[.(value), on = seg.var]
data.select.dt.V4 <- function(dset, seg.var, value) {
if(!data.table::is.data.table(dset)) dset <- data.table::as.data.table(dset) # To convert only if needed
dset[.(value), on = seg.var]
}
expr min lq mean median uq max neval cld
1 res <- data.select.dt.V1(iris_df, "Species", "setosa") 3.804995 4.585763 4.150130 4.688093 5.320362 3.166503 10 c
2 res <- data.select.dt.V2(iris_df, Species, "setosa") 3.713275 3.827180 3.865347 4.544968 4.753045 3.218075 10 c
3 res <- data.select.dt.V3(iris_df, "Species", "setosa") 1.927947 1.942868 2.167127 2.328364 2.595420 2.159664 10 b
4 res <- data.select.dt.V4(iris_df, "Species", "setosa") 1.987710 2.004497 2.011502 2.280117 2.856847 1.594249 10 b
5 res <- data.select.dt.V1(iris_dt, "Species", "setosa") 2.771223 2.792428 2.501362 2.805796 3.056144 1.883520 10 b
6 res <- data.select.dt.V2(iris_dt, Species, "setosa") 2.830161 2.970071 2.593192 3.123812 3.170884 1.752576 10 b
7 res <- data.select.dt.V3(iris_dt, "Species", "setosa") 1.963530 2.116116 2.059718 2.203265 2.740949 1.768817 10 b
8 res <- data.select.dt.V4(iris_dt, "Species", "setosa") 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 10 a
顯然V4
是一個至如果你期望data.frame
和data.table
,如果只有df
是可能的,最快的功能將是V3
。
爲什麼你要在函數內轉換爲data.table?您正在創建整個數據集的副本。通過使用'setDT'將其轉換爲一個''data.table''就更好了。無論哪種方式,我會做一個簡單的二進制連接。像'data.select.dt < - 函數(dset,seg.var,value)as.data.table(dset)[。(value),on = seg.var]',然後將其作爲data.select運行.dt(iris,「Species」,「setosa」)' –
我想確保其餘的代碼能夠正常工作。由於我使用的數據集大於'iris',因此我想比較「base」子集的性能和'data.table'中實現的性能,而不必強制重寫整個代碼。 – kaksat
@kaksat,在我的答案中查看'if(!data.table :: is.data.table(dset))',如果'dset'是'data.table',應該節省一些時間和RAM。 –