سؤال

لدي بعض الرمز حيث يكون الاتصال أكثر ملاءمة 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"))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top