في R data.table، كيف يمكنني تمرير معلمات متغيرة إلى تعبير؟
-
12-12-2019 - |
سؤال
أنا عالق في مشكلة R صغيرة مع data.table
.مساعدتكم هو محل تقدير كبير.كيف أقوم بهذا العمل:
getResult <- function(dt, expr, gby) {
e <- substitute(expr)
b <- substitute(gby)
return(dt[,eval(e),by=b])
}
v1 <- "Sepal.Length"
v2 <- "Species"
dt <- data.table(iris)
rDT <- getResult(dt, sum(v1, na.rm=TRUE), v2)
أحصل على الخطأ التالي:
خطأ في sum(v1, na.rm = TRUE):"نوع" (حرف) غير صالح من الوسيطة
الآن كلاهما v1
و v2
يتم تمريرها من برنامج آخر كمتغير حرف لذا لا يمكنني القيام بذلك v1<- quote(Sepal.Length)
والذي يبدو أنه يعمل.
المحلول
يمكن أن يكون البديل لإجابة flodel في التعليقات
e <- parse(text = paste0("sum(", v1, ", na.rm = TRUE)"))
b <- parse(text = v2)
rDT2 <- dt[, eval(e), by = eval(b)]
# b V1
# [1,] setosa 250.3
# [2,] versicolor 296.8
# [3,] virginica 329.4
يحرر:
ولوضع هذا في وظيفة،
getResult <- function(dt, expr, gby){
return(dt[, eval(expr), by = eval(gby)])
}
(dtR <- getResult(dt = dt, expr = e, gby = b))
# gives the same result as above
تحرير من ماثيو:هناك سبب خفي وراء paste0
و eval
\ quote
يمكن أن تكون الأساليب أسرع من get
في بعض الحالات أيضًا.أحد الأسباب التي تجعل التجميع سريعًا هو ذلك data.table
يتفقد j
لمعرفة الأعمدة التي يستخدمها، قم فقط بتقسيم الأعمدة المستخدمة إلى مجموعات فرعية (الأسئلة الشائعة 1.12 و3.1).يستخدم base::all.vars(j)
للقيام بذلك.عند الاستخدام get()
في j
العمود المستخدم مخفي من all.vars
و data.table
يعود إلى تعيين كافة الأعمدة فرعيًا فقط في حالة حدوث ذلك j
التعبير يحتاج إليهم (يشبه إلى حد كبير عندما يكون .SD
يستخدم الرمز في j
, ، لأي منهم .SDcols
تمت إضافته للحل).إذا تم استخدام جميع الأعمدة على أي حال، فلن يحدث ذلك فرقًا، ولكن إذا DT
يقول 1e7x100 ثم مجمعة j=sum(V1)
ينبغي أن يكون أسرع بكثير من تجميعها j=sum(get("V1"))
لهذا السبب.على الأقل هذا ما يفترض أن يحدث، وإذا لم يحدث فقد يكون خطأ.ومن ناحية أخرى، إذا تم إنشاء العديد من الاستعلامات ديناميكيًا وتكرارها، فقد حان الوقت لذلك paste0
و parse
قد يأتي في ذلك.كل هذا يتوقف حقا.جلسة verbose=TRUE
يجب طباعة رسالة حول الأعمدة التي تم اكتشافها على أنها مستخدمة من قبل j
, ، حتى يمكن التحقق من ذلك.