DiveFreedom
DiveFreedom

Reputation: 122

Fill-in column based on multiple and nested conditions in R

I am simulating a dataset for an assignment, and I need help, I looked for hours but couldn't find a way to fix my problem. I will explain quickly:

I have 2 variables:

I want to generate a 3rd variable, that depends on those 2 independently, which is an abundance of dolphins (poisson distribution). So basically, the thing that needs to change is my lambda. The only way I found so far to do that is by doing 4 times a different vector, one for each season. And in the end, putting them 4 together.

My code works fine, but it's awfully and ridiculously long and I know that I could shorten it! But I don't know how... Please help :D

Thanks in advance!!!

My code so far:

abundance_summer <- rep(NA, length(bottom_depth))
set.seed(5)
for (i in 1:length(abundance_summer)){
    if (bottom_depth[i] < 100){
    abundance_summer[i] <- rpois(n=1, lambda=0)
  } else if (bottom_depth[i] > 100 & bottom_depth[i] < 400){
    abundance_summer[i] <- rpois(n=1, lambda=2)
  } else if (bottom_depth[i] > 400 & bottom_depth[i] < 700){
    abundance_summer[i] <- rpois(n=1, lambda=4)
  } else if (bottom_depth[i] > 700 & bottom_depth[i] < 1000){
    abundance_summer[i] <- rpois(n=1, lambda=6)
  } else if (bottom_depth[i] > 1000){
    abundance_summer[i] <- rpois(n=1, lambda=8)
  }
}

abundance_spring <- rep(NA, length(bottom_depth))
set.seed(5)
for (i in 1:length(abundance_spring)){
  if (bottom_depth[i] < 100){
    abundance_spring[i] <- rpois(n=1, lambda=2)
  } else if (bottom_depth[i] > 100 & bottom_depth[i] < 400){
    abundance_spring[i] <- rpois(n=1, lambda=6)
  } else if (bottom_depth[i] > 400 & bottom_depth[i] < 700){
    abundance_spring[i] <- rpois(n=1, lambda=13)
  } else if (bottom_depth[i] > 700 & bottom_depth[i] < 1000){
    abundance_spring[i] <- rpois(n=1, lambda=20)
  } else if (bottom_depth[i] > 1000){
    abundance_spring[i] <- rpois(n=1, lambda=19)
  }
}

abundance_autumn <- rep(NA, length(bottom_depth))
set.seed(5)
for (i in 1:length(abundance_autumn)){
  if (bottom_depth[i] < 100){
    abundance_autumn[i] <- rpois(n=1, lambda=1)
  } else if (bottom_depth[i] > 100 & bottom_depth[i] < 400){
    abundance_autumn[i] <- rpois(n=1, lambda=3)
  } else if (bottom_depth[i] > 400 & bottom_depth[i] < 700){
    abundance_autumn[i] <- rpois(n=1, lambda=6)
  } else if (bottom_depth[i] > 700 & bottom_depth[i] < 1000){
    abundance_autumn[i] <- rpois(n=1, lambda=4)
  } else if (bottom_depth[i] > 1000){
    abundance_autumn[i] <- rpois(n=1, lambda=8)
  }
}

abundance_winter <- rep(NA, length(bottom_depth))
set.seed(5)
for (i in 1:length(abundance_winter)){
  if (bottom_depth[i] < 100){
    abundance_winter[i] <- rpois(n=1, lambda=2)
  } else if (bottom_depth[i] > 100 & bottom_depth[i] < 400){
    abundance_winter[i] <- rpois(n=1, lambda=6)
  } else if (bottom_depth[i] > 400 & bottom_depth[i] < 700){
    abundance_winter[i] <- rpois(n=1, lambda=23)
  } else if (bottom_depth[i] > 700 & bottom_depth[i] < 1000){
    abundance_winter[i] <- rpois(n=1, lambda=16)
  } else if (bottom_depth[i] > 1000){
    abundance_winter[i] <- rpois(n=1, lambda=10)
  }
}

common_dolphins_abundance <- c(abundance_autumn, abundance_spring,abundance_summer, abundance_winter)

Upvotes: 1

Views: 80

Answers (1)

Maurits Evers
Maurits Evers

Reputation: 50668

How about this?

You don't give bottom_depth so I will generate some random numbers.

set.seed(5);
bottom_depth <- runif(100, 0, 2000);

Bin bottom_depth values based on your 5 ranges.

# Bin depth into 5 ranges
breaks.depth <- cut(bottom_depth, breaks = c(0, 100, 400, 700, 1000, max(bottom_depth)));

Store lambda parameters in a dataframe, where columns correspond to seasons, and rows to depth bins.

# Dataframe of lambda parameters for every month for every depth bin
df.lambda <- data.frame(
    summer = c(0, 2, 4, 6, 8),
    spring = c(2, 6, 13, 20, 19),
    autumn = c(1, 3, 6, 4, 8),
    winter = c(2, 6, 23, 16, 10));

For every season, generate Poisson-distributed samples, one for every lambda value:

abundance <- lapply(df.lambda, function(x) {
    rpois(length(bottom_depth), lambda = x[as.numeric(breaks.depth)])
})
#$summer
#  [1]  7 10  8  7  3  7  6  8  8  1  2  6  5  6  4  3  6  5  8  5  5 14  6  6  1
# [26]  2  7 10  1  7  5  1  0  0  0  8  7  2  3  5  7  4  7  6  7 12  9  3  8  9
# [51]  7  9  7  9 11  3  4  5  2  1  6  3  9  7  3 12 11  2  8  5 10 14  1 12  0
# [76] 15  0  3  5  6  8 14  3  0  8  3  5  8  5  4 11  2  3  4  5 10  3 12  5  5
#
#$spring
#  [1] 12 18 10 14  6 19 18 22 18  2 11 20 18 30 13  8 13 21 19 18 24 22 19  8  4
# [26] 23 22 20  3 14 21  4 10  6  1 24 17 17 20 18 12 17 14 16 10 24 17  9 18 22
# [51] 11 18 18 16 15 32 11 13  6  8 27  9 23 13 15 17 22  3 23 16 16 25  9 24  3
# [76] 22  5 16 15 11 23 15 12  7 22  8 20 22 14 17 16 11  8 16 12 25 14 21 20 19
#
#$autumn
#  [1] 11  4  7  1  1  4  7 13  3  2  5  4  4  7  0  3  3  3 11 10  6 14  4  6  2
# [26]  8  8 15  6 10  2  4  5  1  2  5  9  2  4  6  8  6 12  8  4  8  6  3  9 11
# [51]  3  7  5 13  9  3  5  4  2  3  8  0  7  9  3 12  4  1  6  6  6  6  4  4  1
# [76]  4  0  8  4  8 11  7  4  2  4  4 15 12  8  9  6  7  1  5  4  7  5  4  2  6
#
#$winter
#  [1] 19 14 12 21  3 10 10  9 10  4 22 23 22 12 26 28 17  7  9 12 11 10 23 19  7
# [26] 19 16 10  9  8 21  6 23  0  2 12 15 10 22 20  6 26  6 13 12  7  5  3  8 14
# [51] 17 12  7  9 15 10 19 23  4  6  8  6 11  7  7 11 10  0  9 11  8 13  6  7  1
# [76]  5  2 13  7 19  8  9 25 11 22  7  3 16 25 13  8 28  4 23 27 13 22 10 16 15

Upvotes: 4

Related Questions