0
votes

I'm attempting to independently select elements of an array that meet a condition and then convert those elements to a different value, with a given frequency. In R I'd use rbinom, but can't find the correct function in Julia. MWE:

#create array
a = [3,4,3,6,3];

# convert elements that match ==3 to 9
a[a .==3] .=9;

a
[9,4,9,6,9]

but what I can't figure out how to do is the conversion with binomial probability (might be bernoulli?) of, for example, 0.66 so converted a might end up as

[3,4,9,6,9]

I think what I want is something like:

a[a .==3] .= bernoulli(0.66)9

Such that the probability of being converted from 3 to 9 is 0.66. So 66% of the time it will convert the 3 to 9, and the remaining 33% it will just leave it as a 3. Make sense?

I'd like to do the evaluation independently on each instance of 3, rather than extracting an index vector of all the 3's and then calculating how many are converted with a probability (if that makes any sense?!) Thx J

1
I'm not sure I understand. All elements equal to 3 should be replaced by 9 with probability 0.66, and left as is with probability 1-0.66, is that what you want? Perhaps just provide the R code snippet that does what you want.phipsgabler
Yes that is it. It is for a biological model where the "state" of the individual changes from one state, eg. 3 to a different state, eg. 9 with a given daily probability. In R I would use "rbinom(1, 1, 0.66)*9" although there may be a simpler, more elegant way?Jim Maas
That R snippet is confusing. Where is the input vector? Why multiply with the number 9? What happened to 3?DNF
Apologies @DNF, not shown in the comment here. I am a bit surprised, moving from R to Julia, it seems Julia is very powerful with many complex functions built in so I think I'm just missing something. I've searched but not found, will try your solution below. Thx.Jim Maas
I'm not saying that there is no built-in function like this, or maybe some library has it. But looking at the documentation for rbinom in R, it doesn't look like it has anything to do with replacements in vectors, only with generating random values. If you want something like that, look at the Distributions.jl package, and you can find something relevant. My code does not replicate the functionality of rbinom, but of the replacement functionality you described in your post.DNF

1 Answers

0
votes

I don't know any pre-made solution here (I'm not familiar with the field really), but you can roll your own solution easily.

I think you should be using a Bernoulli distribution actually, unless I'm mistaken. You can either use Bernoulli from Distributions.jl, or you can make your own with plain old rand:

using Distributions: Bernoulli

function rbinom!(xs, subst::Pair, p=1.0)
    (x, y) = subst
    dist = Bernoulli(p)
    for (i, val) in pairs(xs)
        if val == x && rand(dist)
            xs[i] = y
        end
    end
    return xs
end

If you don't want to import Distributions.jl, you can just write

function rbinom!(xs, subst::Pair, p=1.0)
    (x, y) = subst
    for (i, val) in pairs(xs)
        if val == x && rand() < p  # or rand() <= p ?
            xs[i] = y
        end
    end
    return xs
end

You call it like this:

julia> a = [3,4,3,6,3];

julia> rbinom!(a, 3=>9, 0.66)
5-element Array{Int64,1}:
 9
 4
 9
 6
 3

Note that this function updates the vector a in-place. If you don't want that you can create a wrapper function that sends in a copy of a:

rbinom(xs, args...) = rbinom!(copy(xs), args...)