ما هي الاختلافات بين عوامل التخصيص "=" و"<-" في R؟

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

  •  20-09-2019
  •  | 
  •  

سؤال

ما هي الاختلافات بين مشغلي المهمة = و <- في ر؟

أعلم أن عوامل التشغيل مختلفة قليلاً، كما يوضح هذا المثال

x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"

لكن هل هذا هو الفرق الوحيد؟

هل كانت مفيدة؟

المحلول

ما هي الاختلافات بين مشغلي المهمة = و <- في ر؟

كما يظهر المثال الخاص بك، = و <- لها أسبقية عامل تشغيل مختلفة قليلاً (والتي تحدد ترتيب التقييم عند مزجها في نفس التعبير).في الحقيقة، ?Syntax في R يعطي جدول أسبقية عامل التشغيل التالي، من الأعلى إلى الأدنى:

…
‘-> ->>’           rightwards assignment
‘<- <<-’           assignment (right to left)
‘=’                assignment (right to left)
…

لكن هل هذا هو الفرق الوحيد؟

منذ أن كنت تسأل عن مشغلي التعيين:نعم، هذا هو الفرق الوحيد.ومع ذلك، سوف يغفر لك الاعتقاد بخلاف ذلك.حتى توثيق R لـ ?assignOps يدعي أن هناك المزيد من الاختلافات:

المشغل <- يمكن استخدامها في أي مكان ، في حين أن المشغل = يُسمح به فقط في المستوى الأعلى (على سبيل المثال ، في التعبير الكامل المكتوبة في موجه الأوامر) أو كواحد من التعبيرات الفرعية في قائمة التعبيرات المستردة.

دعونا لا نضع نقطة جيدة جدًا حول هذا الموضوع: وثائق R خاطئة (بمهارة). [1].من السهل إظهار ذلك:نحتاج فقط إلى العثور على مثال مضاد لـ = عامل تشغيل ليس (أ) في المستوى الأعلى، ولا (ب) تعبيرًا فرعيًا في قائمة تعبيرات بين قوسين (أي {…; …}).- دون مزيد من اللغط:

x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1

من الواضح أننا قمنا بمهمة باستخدام =, خارج السياقين (أ) و (ب).إذًا، لماذا كان توثيق ميزة لغة R الأساسية خاطئًا لعقود من الزمن؟

هذا لأنه في بناء جملة R الرمز = له معنيان متميزان يتم الخلط بينهما بشكل روتيني:

  1. المعنى الأول هو مثل مهمة تشغيل.وهذا كل ما تحدثنا عنه حتى الآن.
  2. المعنى الثاني ليس عاملاً بل أ رمز بناء الجملة تلك الإشارات تمرير الوسيطة المسماة في استدعاء دالة.على عكس = المشغل لا ينفذ أي إجراء في وقت التشغيل، فهو يغير فقط الطريقة التي يتم بها تحليل التعبير.

دعنا نرى.

في أي جزء من التعليمات البرمجية للنموذج العام ...

<اسم وظيفة>(‹اسم الوسيط› = <قيمة>, …)
<اسم وظيفة>(‹الوسائط›, ‹اسم الوسيط› = <قيمة>, …)

… ال = هو الرمز المميز الذي يحدد تمرير الوسيطة المسماة:إنها لا عامل المهمة.بالإضافة إلى، = تماما مُحرَّم في بعض السياقات النحوية:

if (‹فار› = <قيمة>) …
while (‹فار› = <قيمة>) …
for (‹فار› = <قيمة> in ‹القيمة2›) …
for (‹فار1› in ‹فار2› = <قيمة>) …

سيؤدي أي منها إلى ظهور خطأ "غير متوقع '=' في ‹bla›".

وفي أي سياق آخر، = يشير إلى استدعاء مشغل المهمة.على وجه الخصوص، مجرد وضع قوسين حول التعبير الفرعي يجعل أيًا مما سبق (أ) صالحًا، و(ب) تكليف.على سبيل المثال، يقوم ما يلي بتنفيذ المهمة:

median((x = 1 : 10))

لكن أيضا:

if (! (nf = length(from))) return()

الآن قد تعترض على أن مثل هذا الكود فظيع (وقد تكون على حق).لكنني أخذت هذا الرمز من base::file.copy وظيفة (استبدال <- مع =) - إنه نمط منتشر في الكثير من قاعدة بيانات R الأساسية.

ال التفسير الأصلي لجون تشامبرز, ، والتي من المحتمل أن تستند إليها وثائق R، تشرح هذا بشكل صحيح:

[= [التكليف] مسموح به في موضعين فقط من النحو:في المستوى الأعلى (كبرنامج كامل أو تعبير يكتبه المستخدم)؛وعندما يتم عزلها عن البنية المنطقية المحيطة بها، بواسطة قوسين أو زوج إضافي من الأقواس.


اعتراف:لقد كذبت في وقت سابق.هناك يكون فرق إضافي واحد بين = و <- العاملين:يسمونها وظائف متميزة.بشكل افتراضي، تقوم هذه الوظائف بنفس الشيء ولكن يمكنك تجاوز أي منهما بشكل منفصل لتغيير السلوك.على نقيض ذلك، <- و -> (التعيين من اليسار إلى اليمين)، على الرغم من اختلافه النحوي، يستدعي دائمًا نفس وظيفة.تجاوز أحدهما يلغي الآخر أيضًا.نادرًا ما تكون معرفة ذلك أمرًا عمليًا لكنه يستطيع يمكن استخدامها لبعض الخدع الممتعة.

نصائح أخرى

الفرق في مشغلي التعيين يكون أكثر وضوحًا عند استخدامها لتعيين قيمة وسيطة في استدعاء دالة.على سبيل المثال:

median(x = 1:10)
x   
## Error: object 'x' not found

في هذه الحالة، x تم الإعلان عنه ضمن نطاق الوظيفة، لذا فهو غير موجود في مساحة عمل المستخدم.

median(x <- 1:10)
x    
## [1]  1  2  3  4  5  6  7  8  9 10

في هذه الحالة، x تم الإعلان عنه في مساحة عمل المستخدم، بحيث يمكنك استخدامه بعد اكتمال استدعاء الوظيفة.


هناك تفضيل عام بين مجتمع R للاستخدام <- للتخصيص (بخلاف التوقيعات الوظيفية) للتوافق مع الإصدارات القديمة (جدًا) من S-Plus.لاحظ أن المسافات تساعد في توضيح المواقف مثل

x<-3
# Does this mean assignment?
x <- 3
# Or less than?
x < -3

تحتوي معظم R IDEs على اختصارات لوحة المفاتيح لإنشاءها <- أسهل في الكتابة. كنترول + = في المهندس المعماري, بديل + - في رستوديو (خيار + - ضمن نظام التشغيل MacOS)، يحول + - (تسطير أسفل السطر) في emacs+ESS.


إذا كنت تفضل الكتابة = ل <- ولكنك تريد استخدام رمز المهمة الأكثر شيوعًا للتعليمات البرمجية الصادرة للعامة (على CRAN، على سبيل المثال)، فيمكنك استخدام أحد الرموز tidy_* وظائف في formatR الحزمة لتحل محلها تلقائيا = مع <-.

library(formatR)
tidy_source(text = "x=1:5", arrow = TRUE)
## x <- 1:5

الجواب على السؤال "لماذا x <- y = 5 رمي خطأ ولكن لا x <- y <- 5؟" هو "الأمر يعود إلى السحر الموجود في المحلل اللغوي".يحتوي بناء جملة R العديد من الحالات الغامضة والتي يجب حلها بطريقة أو بأخرى.يختار المحلل اللغوي تحليل أجزاء التعبير بترتيبات مختلفة اعتمادًا على ما إذا كان ذلك أم لا = أو <- كان مستعملا.

لفهم ما يحدث، عليك أن تعرف أن التعيين يُرجع القيمة التي تم تعيينها بصمت.يمكنك أن ترى ذلك بشكل أكثر وضوحًا من خلال الطباعة بشكل صريح، على سبيل المثال print(x <- 2 + 3).

ثانيًا، يكون الأمر أكثر وضوحًا إذا استخدمنا تدوين البادئة للمهمة.لذا

x <- 5
`<-`(x, 5)  #same thing

y = 5
`=`(y, 5)   #also the same thing

المحلل يفسر x <- y <- 5 مثل

`<-`(x, `<-`(y, 5))

ربما نتوقع ذلك x <- y = 5 سيكون بعد ذلك

`<-`(x, `=`(y, 5))

ولكن في الواقع يتم تفسيره على أنه

`=`(`<-`(x, y), 5)

هذا بسبب = هي أسبقية أقل من <-, ، كما هو مبين على ?Syntax صفحة المساعدة.

ودليل R أسلوب جوجل يبسط المسألة من خلال حظر "=" للمهمة. ليس خيارا سيئا.

https://google.github.io/styleguide/Rguide.xml

والدليل R يذهب الى التفاصيل لطيفة على جميع المشغلين احالة 5.

HTTP: //stat.ethz. الفصل / R اليدوية مصححة R / / المكتبة / قاعدة / أتش تي أم أل / assignOps.html

وx = y = 5 ما يعادل x = (y = 5)، لأن عوامل التعيين "مجموعة" من اليمين إلى اليسار، والذي يعمل. وهذا يعني: تعيين 5 إلى y، وترك رقم 5؛ ثم قم بتعيين أن 5 إلى x.

وهذه ليست هي نفسها كما (x = y) = 5، الذي لا يعمل! المعنى: تعيين قيمة y إلى x، وترك قيمة y. ثم قم بتعيين 5 ل، أم ...، ماذا بالضبط؟

عند خلط أنواع مختلفة من عوامل التعيين، <- يربط أكثر تشددا من =. حتى يتم تفسير x = y <- 5 كما x = (y <- 5)، وهي القضية التي من المنطقي.

ولسوء الحظ، يتم تفسير x <- y = 5 كما (x <- y) = 5، وهي الحالة التي لا عمل!

وانظر ?Syntax و?assignOps للالأسبقية (ملزمة) وتجميع القواعد.

ووفقا لجون تشامبرز، ولا يسمح لل= المشغل الوحيد في "مستوى أعلى"، مما يعني أنه لا يجوز في هياكل المراقبة مثل if، مما يجعل الخطأ التالي البرمجة غير قانونية.

> if(x = 0) 1 else x
Error: syntax error

وكما يكتب، "عدم السماح شكل مهمة جديدة [=] في التعبيرات السيطرة يتجنب أخطاء البرمجة (مثل المثال أعلاه) التي يرجح مع المشغل على قدم المساواة مع من مهام S أخرى."

ويمكنك يتمكن من القيام بذلك اذا كان "معزولة عن البنية المنطقية المحيطة، من خلال الأقواس أو اضافية زوج من الأقواس،" لذلك if ((x = 0)) 1 else x ستعمل.

http://developer.r-project.org/equalAssign.html

المشغلين <- و = تعيينهم في البيئة التي يتم تقييمهم فيها.المشغل <- يمكن استخدامها في أي مكان، بينما المشغل = مسموح به فقط في المستوى الأعلى (على سبيل المثال، في التعبير الكامل المكتوب في موجه الأوامر) أو كأحد التعبيرات الفرعية في قائمة التعبيرات بين قوسين.

وهذا قد تضيف أيضا لفهم الفرق بين تلك الشركتين:

df <- data.frame(
      a = rnorm(10),
      b <- rnorm(10)
)

لأول R عنصر كلفت القيم والاسم الصحيح، في حين أن اسم العنصر الثاني يبدو غريبا بعض الشيء.

str(df)
# 'data.frame': 10 obs. of  2 variables:
#  $ a             : num  0.6393 1.125 -1.2514 0.0729 -1.3292 ...
#  $ b....rnorm.10.: num  0.2485 0.0391 -1.6532 -0.3366 1.1951 ...

وR نسخة 3.3.2 (2016/10/31)؛ ماك سييرا 10.12.1

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