0

I have a sampling function of:

z = rnorm(n, 0.3, 1)

And would like my variable f to equal 1 if -pi < z_i < pi and equal 0 otherwise.

I'm not sure how to achieve this. My other idea was to use a reject function but this seems overly complicated.

M--
  • 25,431
  • 8
  • 61
  • 93
  • `z <- abs(rnorm(n, 0.3, 1)) – DanY Mar 15 '19 at 16:03
  • @DanY Very close, you needed to convert Boolean to Integer. `f <- +abs(rnorm(n, 0.3, 1)) – M-- Mar 15 '19 at 16:05
  • 1
    I suppose adding the `+` gets exactly what the OP requested. But R converts boolean to integer/double anytime you use a boolean in a mathematical expression. The only time I would store a boolean explicitly as 0/1 is if I needed to display the data and that display was horizontally constrained. But maybe that's just me. – DanY Mar 15 '19 at 16:12

2 Answers2

0

Here you can use the function ifelse, which does exactly what you want: to return a value if a condition satisfies, and another different if not. For example, for n= 10 and pi=1:

f = ifelse (rnorm(n=10, 0.3, 1) > 1,1,0)

You should easily figure out how to solve your problem with this example.

You could also save your results in a temporal vector, and then check the exact condition you want with boolean operators:

ri = rnorm(n=10, 0.3, 1)
ifelse(-1 < ri & ri < 1,1,0)

Following @M-M comment, you can also obtain values of 1 or 0 just from the evaluated conditional expression. For instance:

as.integer(-1 < ri & ri < 1)
elcortegano
  • 2,444
  • 11
  • 40
  • 58
  • 2
    You don't need `ifelse`. Boolean can be converted to integers. And just couple days ago *Emma Haruka Iwao* calculated pi to 31.4 trillion decimal places. https://www.washingtonpost.com/business/2019/03/14/google-employee-breaks-guinness-world-record-calculating-trillion-digits-pi/?utm_term=.49e0aa0d838b ... let's set pi to 3.14 at least. p.s. ***`pi` is already in r!!!*** ;) – M-- Mar 15 '19 at 16:08
  • You're right, but assuming OP is learning the basics I feel this can provide an easily generalizable solution. Happi-pi day!! – elcortegano Mar 15 '19 at 16:11
  • I am sorry to push further. But assigning values to the reserved parameters is bad practice. I strongly recommend deleting `pi = 1` line. Besides that, consider flagging for duplicates for these kind of questions instead of posting an answer. Cheers. – M-- Mar 15 '19 at 16:14
0

Assuming you have created the variable z, then you can do this with ifelse():

f <- ifelse(abs(z) < pi, 1, 0)

Or with:

f <- as.integer(abs(z) < pi)

The second one might be quicker, although you probably won't notice unless n is large.

EDIT: The second one is much faster: just checked it on a vector of 1,000,000 values and the first takes 0.2 seconds, the second method shows elapsed 0!

Hamed
  • 206
  • 2
  • 8
  • `elapsed 0`? do you mind sharing your bench-marking? p.s there is a library called [`microbenchmark`](https://www.rdocumentation.org/packages/microbenchmark/versions/1.4-6/topics/microbenchmark) in r. That's a better practice for comparing different methods. p.s.2. second one is faster! – M-- Mar 15 '19 at 16:16
  • Yes you're right: I was about to leave the office and just ran it once! Running on `microbenchmark` gives median times of 94 and 9 milliseconds respectively, so the `f <- as.integer(abs(z) < pi)` is definitely a lot faster. – Hamed Mar 16 '19 at 22:08