لماذا لا تستطيع أن ترجع عبارات IFELSE المتجهات؟
-
20-09-2019 - |
سؤال
لقد وجدت ص العبارات IFELSE هي مفيد جدا من وقت لآخر. علي سبيل المثال:
ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2
لكنني مرتبك إلى حد ما من السلوك التالي.
ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3
هل هذا خيار التصميم الذي هو فوق بلدي Paygrade؟
المحلول
الوثائق ل ifelse
تنص على:
ifelse
إرجاع قيمة بنفس الشكلtest
التي تملأ العناصر المحددة من أيyes
أوno
اعتمادا على ما إذا كان عنصرtest
هوTRUE
أوFALSE
.
نظرا لأنك تمر بقيم اختبار الطول 1، فأنت تحصل على نتائج الطول 1. إذا قمت بتمرير ناقلات اختبار أطول، فستحصل على نتائج أطول:
> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4
لذا ifelse
ويهدف لغرض محدد في اختبار متجه من المنطاقين وإعادة متجه من نفس الطول، مليء عناصر مأخوذة من (ناقل) yes
و no
الحجج.
إنه ارتباك مشترك، بسبب اسم الوظيفة، لاستخدام هذا عندما تريد حقا عادي if () {} else {}
البناء بدلا من ذلك.
نصائح أخرى
أراهن أنك تريد بسيطة if
بيان بدلا من ifelse
- في ص، if
ليس مجرد هيكل تدفق التحكم، يمكنه إرجاع قيمة:
> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4
لاحظ أنه يمكنك التحايل على المشكلة إذا قمت بتعيين النتيجة داخل ifelse
:
ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2
ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4
نعم، أعتقد أن IFELSE () مصممة حقا عندما يكون لديك ناقلات طويلة كبيرة من الاختبارات وتريد تعيين كل من خيارين. على سبيل المثال، كثيرا ما أفعل الألوان للمؤامرة () بهذه الطريقة:
plot(x,y, col = ifelse(x>2, 'red', 'blue'))
إذا كان لديك ناقلات طويل كبير من الاختبارات ولكن أراد أزواج للمخرجات، فيمكنك استخدامها sapply()
أو plyr
'س llply()
أو شيء ما، ربما.
فيما يلي نهج مشابه لتلك التي اقترحها كاث، ولكن يمكن أن تعمل مع ناقلات موجودة مسبقا
ويستند حول استخدام get()
مثل ذلك:
a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2
في بعض الأحيان يحتاج المستخدم فقط switch
بيان بدلا من ifelse
. وبعد في هذه الحالة:
condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2
(وهو خيار بناء جملة آخر لإجابة كين ويليامز)
استخدام `إذا`، على سبيل المثال
> `if`(T,1:3,2:4)
[1] 1 2 3
في حالتك، باستخدام if_else
من عند dplyr
سيكون مفيدا: if_else
هو أكثر صرامة من ifelse
, ويطرح خطأ لحالتك:
library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2