هل يمكنك استخدام الإصلاح عبر do.call؟
سؤال
لدي بعض الرمز حيث يكون الاتصال أكثر ملاءمة fix
عبر do.call
, ، بدلا من مباشرة. أي إطار بيانات قديم سيعمل على هذا المثال:
dfr <- data.frame(x = 1:5, y = letters[1:5])
المحاولة الأولى الواضحة هي
do.call("fix", list(dfr))
لسوء الحظ ، فشل هذا
Error in fix(list(x = 1:5, y = 1:5)) : 'fix' requires a name
لذلك ، نعطيه اسمًا:
do.call("fix", list(dfr = dfr))
هذه المرة تفشل معها
Error in is.name(subx) : 'subx' is missing
للسجل ، edit
لا يعمل أيضًا.
dfr <- do.call("edit", list(dfr = dfr))
هل يمكن لأي شخص أن يفكر في حل معقول من فضلك؟
تحرير: عند التفكير ، نسيت ذلك fix
تتفصل دائمًا عن إجابتها في البيئة العالمية ، وهو أمر جيد لأمثلة الاختبار ، ولكن ليس جيدًا للاستخدام مع الوظائف. الحل الممتاز لجوشوا لا يمتد إلى استخدامه edit
.
للحصول على نقاط المكافأة ، كيف تتصل edit
عبر do.call
?
المحلول
يمكنك استخدام substitute
, ، وهو أمر مفيد أيضًا عندما تريد استخدام أسماء متغيرة كعلامات.
do.call("fix",list(substitute(dfr)))
تحرير للوضوح
من الأسهل معرفة كيفية عمل هذا باستخدام call
يأمر:
> call("fix",dfr)
fix(list(x = c(1, 2, 3, 4, 5), y = 1:5))
> call("fix",substitute(dfr))
fix(dfr)
وهكذا عندما تستخدم substitute
يستخدم الأمر الذي يتم إنشاؤه اسم الرمز بدلاً من الرمز الذي تم تقييمه. إذا لفت eval
حول هذه التعبيرات ، ترى أن المثال الأول يعطي نفس الخطأ الذي واجهته ، والمثال الثاني يعمل كما هو متوقع.
بعد قراءة رابط هادلي ، يصبح الأمر أكثر وضوحًا ما يتم تقييمه:
> as.name("dfr")==substitute(dfr)
[1] TRUE
نصائح أخرى
الخطأ الأول يمنحك تلميحًا. هذا يعمل:
do.call(fix,list("dfr"))
ستظل تحصل على نفس الخطأ في المحاولة الثانية حتى لو كنت تستخدم dfr="dfr"
لأن القائمة المسماة تحتاج إلى أسماء الحجج إلى what
(الوظيفة). لذلك يجب أن تكون محاولتك الثانية:
do.call(fix,list(x="dfr"))