# Selecting agents of a specific class in agents.jl

**URL:** <https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486>\
**Category:** Modelling & Simulations\
**Created:** [July 25, 2024, 5:35pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486 "2024-07-25T17:35:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![geoffD](https://avatars.discourse-cdn.com/v4/letter/g/cdc98d/32.png) [@geoffD](https://discourse.julialang.org/u/geoffD)\
**Post date:** [July 25, 2024, 5:35pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/1 "2024-07-25T17:35:37Z")

</div>

Hi, I have an agents.jl model that uses two classes of GridAgent: Nurse and Patient.

I’d like the step function to locate an available nurse and link them to an available patient:

```julia
function nursepatient_step!(nurse::Nurse, model) 
   if nurse.patient_id == -1 
         patient = random_agent(model, patient -> typeof(patient) == "Patient" & patient.nurse_id == -1 & patient.nurse_complete == false) 
         nurse.patient_id = patient.id
         patient.nurse_id = nurse.id 
         patient.nurse_start_time = abmtime(model)
    end
end

```

After reading the documentation, it’s unclear to me how to scope random\_agent to return only Patients.

Additionally, wondering how handle initializing a new agent with some of the parameters missing. In other words, I would like nurse\_id to be missing on initialization. I’ve set this up using -1 as the initial value, but that does not seem ideal.

Thanks for the help!

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 25, 2024, 7:04pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/2 "2024-07-25T19:04:34Z")

</div>

> [@geoffD](#):
>
> `typeof(patient) == "Patient"`

In your condition function you use `typeof(patient) == "Patient"`, but what you need is `typeof(patient) == Patient` because you need to compare types rather than a type to a string.

I’m not quite sure about your other question. My suspicion is that setting the id field manually is not a safe approach. Is there a different way you can identify a specific nurse? Maybe if you create a new nurse who is available, you can have a Boolean field for available.

---

<div class="post-metadata">

**Author:** ![geoffD](https://avatars.discourse-cdn.com/v4/letter/g/cdc98d/32.png) [@geoffD](https://discourse.julialang.org/u/geoffD)\
**Post date:** [July 25, 2024, 7:28pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/3 "2024-07-25T19:28:34Z")

</div>

Hi, thanks for this. I probably should have shared a bit more code. I am cribbing the agent structure from the [predation model](https://juliadynamics.github.io/Agents.jl/stable/examples/predator_prey/):

```julia

using Agents, Random, PoissonRandom

@agent struct Patient(GridAgent{2})
    nurse_req::Int  
    nurse_complete::Bool = false 
    nurse_id::Int = -1 
    nurse_start_time::Int = -1
    nurse_end_time::Int = -1 
    
end

@agent struct Nurse(GridAgent{2})
    patient_id::Int = -1 
end

```

When I update the code as suggested, I get: LoadError: ArgumentError: Agent of type Patient has not been created via `@multiagent`.

So l gather I need to either use a different structure for the agents, or find another way to disambiguate nurses and patients? Not sure which of these paths will be most effective.

With regard to the other question, I’m thinking of nurse\_id and patient\_id as being blank/missing until a nurse and patient are linked. I could not figure out how to initialize agents with missing parameter values, though, so I set them to -1 in place of missing. So when I look for a patient with nurse\_id = -1, I’m really looking for a patient who does not have a linked nurse. I would like to stop using -1 as my proxy for missingness. Hope that’s a better explanation.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 25, 2024, 8:50pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/4 "2024-07-25T20:50:46Z")

</div>

> [@geoffD](#):
>
> I’ve set this up using -1 as the initial value, but that does not seem ideal.

Why not? Using a dummy value is perfectly fine. there is no practical difference in using a dummy value, if a possibility for it exists, and using the formal `undef` of Julia. What you do now is what I’d do as well actually!

> [@geoffD](#):
>
> After reading the documentation, it’s unclear to me how to scope random\_agent to return only Patients

Just give the `condition` function to check whether the type of the agent is what you want in the two-argument version of `random_agent`: [API · Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/api/#Agents.random_agent)

> [@geoffD](#):
>
> When I update the code as suggested, I get: LoadError: ArgumentError: Agent of type Patient has not been created via `@multiagent`.

It’s difficult to understand what you mean here. As suggested by whom and where? The error message you provide seems unrelated with the code you paste. Could you perhaps create a full MWE that creates this error you paste?

---

<div class="post-metadata">

**Author:** ![geoffD](https://avatars.discourse-cdn.com/v4/letter/g/cdc98d/32.png) [@geoffD](https://discourse.julialang.org/u/geoffD)\
**Post date:** [July 26, 2024, 3:00pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/5 "2024-07-26T15:00:12Z")

</div>

> [@Datseris](#):
>
> Why not? Using a dummy value is perfectly fine. there is no practical difference in using a dummy value, if a possibility for it exists, and using the formal `undef` of Julia. What you do now is what I’d do as well actually!

Using a dummy value is fine, as long as there is zero chance the value you’ve chosen will actually be a valid value for that variable in the future. One way to avoid this possibility is to use whatever notation your software/environment assigns to missing values. In this instance, I don’t know enough about how agents.jl assigns agent id’s to be certain -1 will never be an assigned value, so I was hoping to go with missing instead.

> It’s difficult to understand what you mean here. As suggested by whom and where? The error message you provide seems unrelated with the code you paste. Could you perhaps create a full MWE that creates this error you paste?

Earlier in this thread, @Christopher_Fisher had suggested I do something like the following:  
`patient = random_agent(model, patient -> kindof(patient) == Patient )`

When I implemented that change, I received a new error for that line: ArgumentError: Agent of type Patient has not been created via `@multiagent`.

Thus, it appears to me that now that I am using working syntax to refer to agent types, that code is creating an error saying I have not correctly created agents of the type I desire, and that perhaps I need to do this with multiagent.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 26, 2024, 3:11pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/6 "2024-07-26T15:11:23Z")

</div>

use `typeof`, not `kindof`, if your agents are two different types.

---

<div class="post-metadata">

**Author:** ![geoffD](https://avatars.discourse-cdn.com/v4/letter/g/cdc98d/32.png) [@geoffD](https://discourse.julialang.org/u/geoffD)\
**Post date:** [July 26, 2024, 3:12pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/7 "2024-07-26T15:12:42Z")

</div>

Yep, typeof gets it done. Thanks

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 26, 2024, 3:18pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/8 "2024-07-26T15:18:04Z")

</div>

> [@geoffD](#):
>
> One way to avoid this possibility is to use whatever notation your software/environment assigns to missing values. In this instance, I don’t know enough about how agents.jl assigns agent id’s to be certain -1 will never be an assigned value, so I was hoping to go with missing instead.

unforutnately this will make type instability. Agent IDs are positive definite in agents.jl so you can use `-1` freely.

---

<div class="post-metadata">

**Author:** ![geoffD](https://avatars.discourse-cdn.com/v4/letter/g/cdc98d/32.png) [@geoffD](https://discourse.julialang.org/u/geoffD)\
**Post date:** [July 30, 2024, 5:31pm UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/9 "2024-07-30T17:31:57Z")

</div>

Slight variation on the typeof issue discussed above. I am trying to return all agents of a given type for further processing.

I’ve tried (without success) several variants of:

`patients = findall(patient -> typeof(patient) == Patient, allagents(model))`

How can I scope allagents(model) to a given type, or otherwise return a collection of agents of a specific type?

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 31, 2024, 11:01am UTC](https://discourse.julialang.org/t/selecting-agents-of-a-specific-class-in-agents-jl/117486/10 "2024-07-31T11:01:17Z")

</div>

use `<:` instead of `==` as that’s how you enquire for subtyping relationships in Julia.
