টেরিনারি অপারেটর কি আর-তে উপস্থিত রয়েছে?


175

প্রশ্নটি জিজ্ঞাসা করে, সি এর টেরিনারি অপারেটরের মতো আর-তে কোনও নিয়ন্ত্রণ ক্রম রয়েছে ? যদি তা হয় তবে আপনি এটি কীভাবে ব্যবহার করবেন? ধন্যবাদ!


1
আপনি কি আরও শক্তিশালী কিছু চান ifelse, বা আরও একটি কমপ্যাক্ট ফর্ম?
কার্ল উইথফট

নিবন্ধন করুন কেবল লেখার সংরক্ষণ করার একটি উপায় if (x>1) y=2 else y=3। লেখার y=জন্য এটির একটি নির্দিষ্ট আবেদন রয়েছে।
ekkanal

উত্তর:


302

যেমনটি ifফাংশন হিসাবে রয়েছে Rএবং সর্বশেষ মূল্যায়ন ফিরিয়ে দেয়, যদি-অন্যটির সমতুল্য হয় ?:

> a <- 1
> x <- if(a==1) 1 else 2
> x
[1] 1
> x <- if(a==2) 1 else 2
> x
[1] 2

আর এর শক্তি ভেক্টরাইজেশন। টার্নারি অপারেটরের ভেক্টরাইজেশন হ'ল ifelse:

> a <- c(1, 2, 1)
> x <- ifelse(a==1, 1, 2)
> x
[1] 1 2 1
> x <- ifelse(a==2, 1, 2)
> x
[1] 2 1 2

মজা করছেন, আপনি সি স্টাইল সংজ্ঞায়িত করতে পারেন ?::

`?` <- function(x, y)
    eval(
      sapply(
        strsplit(
          deparse(substitute(y)), 
          ":"
      ), 
      function(e) parse(text = e)
    )[[2 - as.logical(x)]])

এখানে, আপনার বন্ধনী সম্পর্কে যত্ন নেওয়ার দরকার নেই:

> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
> TRUE ? x*2 : 0
[1] 2
> FALSE ? x*2 : 0
[1] 0

তবে আপনার অ্যাসাইনমেন্টের জন্য বন্ধনী প্রয়োজন :(

> y <- 1 ? 2*3 : 4
[1] 6
> y
[1] 1
> y <- (1 ? 2*3 : 4)
> y
[1] 6

অবশেষে, আপনি সি দিয়ে খুব অনুরূপ উপায়ে করতে পারেন:

`?` <- function(x, y) {
  xs <- as.list(substitute(x))
  if (xs[[1]] == as.name("<-")) x <- eval(xs[[3]])
  r <- eval(sapply(strsplit(deparse(substitute(y)), ":"), function(e) parse(text = e))[[2 - as.logical(x)]])
  if (xs[[1]] == as.name("<-")) {
    xs[[3]] <- r
        eval.parent(as.call(xs))
  } else {
    r
  }
}       

আপনি বন্ধনী থেকে মুক্তি পেতে পারেন:

> y <- 1 ? 2*3 : 4
> y
[1] 6
> y <- 0 ? 2*3 : 4
> y
[1] 4
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4

এগুলি প্রতিদিনের ব্যবহারের জন্য নয়, তবে আর ভাষার কিছু অভ্যন্তরীণ শিখতে পারে।


23

অন্য সবার মতোই বলেছেন, ব্যবহার করুন ifelseতবে আপনি অপারেটরগুলি সংজ্ঞায়িত করতে পারেন যাতে আপনার কাছে প্রায় টের্নারি অপারেটর সিনট্যাক্স থাকে।

`%?%` <- function(x, y) list(x = x, y = y)
`%:%` <- function(xy, z) if(xy$x) xy$y else z

TRUE %?% rnorm(5) %:% month.abb
## [1]  0.05363141 -0.42434567 -0.20000319  1.31049766 -0.31761248
FALSE %?% rnorm(5) %:% month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# or, more generally
condition %?% value1 %:% value2

এটি যদি আপনি %চিহ্নগুলি ছাড়াই অপারেটরগুলি সংজ্ঞায়িত করেন তবে এটি কাজ করে

`?` <- function(x, y) if(x) y[[1]] else y[[2]]
`:` <- function(y, z) list(y, z)

TRUE ? rnorm(5) : month.abb
## [1]  1.4584104143  0.0007500051 -0.7629123322  0.2433415442  0.0052823403
FALSE ? rnorm(5) : month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"

(এটি কাজ করে কারণ এর প্রাধান্য :কম ?

দুর্ভাগ্যক্রমে, এটি তখন বিদ্যমান সহায়তা এবং সিকোয়েন্স অপারেটরগুলিকে ভেঙে দেয়।


5

শুধু একটি কৌতুক হিসাবে, আপনি করতে পারেন পুনরায় সংজ্ঞায়িত ?করতে (প্রায়) তিন অপারেটর মত কাজ অপারেটর (এই একটি খারাপ ধারণা):

`?` <- function(x, y) { y <-substitute(y); if(x) eval(y[[2]], parent.frame()) else eval(y[[3]], parent.frame()) }

x <- 1:3
length(x) ? (x*2) : 0
x <- numeric(0)
length(x) ? (x*2) : 0

for(i in 1:5) cat(i, (i %% 2) ? "Odd\n" : "Even\n")

... তবে আপনাকে এক্সপ্রেশনগুলি বন্ধনীতে রাখতে হবে কারণ ডিফল্ট নজিরটি সি এর মতো হয় না

পুরানো সহায়তা ক্রিয়াকলাপটি পুনঃস্থাপনের জন্য মনে রাখবেন যখন আপনি খেলবেন:

rm(`?`)

5

আমি ifelseকমান্ডটি একবার দেখে নিই । আমি এটিকে আরও ভাল বলব কারণ এটিও ভেক্টরাইজড। গাড়িগুলি ডেটাসেট ব্যবহার করে একটি উদাহরণ:

> cars$speed > 20
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[49]  TRUE  TRUE

> ifelse(cars$speed > 20, 'fast', 'slow')
 [1] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[11] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[21] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[31] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[41] "slow" "slow" "slow" "fast" "fast" "fast" "fast" "fast" "fast" "fast"

4
হাই পল - ifelseআপনার উদাহরণ দিয়ে কিছু বোঝানোর অর্থ কি ? ;)
জোশ ওব্রায়ান

4

আপনার লিঙ্কটি একটি ifবিবৃতিতে নির্দেশ করে।

> x <- 1
> if(x < 2) print("Less than") else print("Greater than")
[1] "Less than"

যদি আপনার ইনপুট ভেরিয়েবলটি ভেক্টর হয় তবে ifelseএটি আরও উপযুক্ত হতে পারে:

> x <- 1:3
> ifelse(x<=2, "Less than or equal", "Greater than")
[1] "Less than or equal" "Less than or equal" "Greater than"   

এর জন্য সহায়তা পৃষ্ঠাটি অ্যাক্সেস করতে ifআপনার ifব্যাকটিক্সে এম্বেড করা দরকার :

?`if`

এর জন্য সহায়তা পৃষ্ঠাটি ifelseএখানে রয়েছে:

`?ifelse`

1
@ কোহস্কে যেমন বলেছেন, এটিও কার্যকর হবে:print(if (x<2) "Less than" else "Greater than")
বেন বলকার

4

এটি সুস্পষ্টভাবে বিদ্যমান নেই, তবে আপনি এটি করতে পারেন:

set.seed(21)
y <- 1:10
z <- rnorm(10)

condition1 <- TRUE
x1 <- if(condition1) y else z

অথবা

condition2 <- sample(c(TRUE,FALSE),10,TRUE)
x2 <- ifelse(condition2, y, z)

দুই এর মধ্যে পার্থক্য যে condition1, দৈর্ঘ্য 1 একটি লজিক্যাল ভেক্টর হতে হবে যখন condition2একটি লজিক্যাল বাহক হিসেবে একই দৈর্ঘ্য হতে হবে x, yএবং z। প্রথম পারেন ফিরে আসবে yবা z(সমগ্র বস্তু), এবং সেকেন্ডের সংশ্লিষ্ট উপাদান ফিরে আসবে y( condition2==TRUE) অথবা z(condition2==FALSE ) ।

এছাড়াও মনে রাখবেন ifelseতুলনায় ধীর হতে হবে if/ elseযদি condition, yএবং zদৈর্ঘ্য 1 সব ভেক্টর হয়।


ধন্যবাদ যিহোশূয় আপনার উত্তর অনেক সাহায্য করেছে, আমি দেখেছি পদ থেকে উত্তর আপনাকে উল্লেখ করেছে stackoverflow.com/a/8792474/3019570
মাহদি Jadaliha

2

if নিম্নলিখিত পদ্ধতিতে যদি ব্যবহার করা হয় তবে অবিচ্ছিন্ন আইফেলের মতো কাজ করে:

`if`(condition, doIfTrue, doIfFalse)

এই ওপলটি ব্যবহার করার সুবিধাটি যখন ভেক্টরাইজেশনটি হয় (যেমন আমার স্ক্যালার বুলিয়ান এবং তালিকা / ভেক্টরের ফলস্বরূপ রয়েছে)

ifelse(TRUE, c(1,2), c(3,4))
[1] 1
`if`(TRUE, c(1,2), c(3,4))
[1] 1 2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.