في R data.table، كيف يمكنني تمرير معلمات متغيرة إلى تعبير؟

StackOverflow https://stackoverflow.com//questions/10675182

  •  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, ، حتى يمكن التحقق من ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top