cdcarrion
cdcarrion

Reputation: 590

how to do an ifelse inside a for

I'm trying to do a loop but I don't know what is wrong. And another question: can the code be more "elegant/fast/clean"?

library(dplyr)

db <- tibble(
  year = seq(1870, 1990, by=1),
  mainsample = rbinom(length(year), size=1, p=0.9)
) 

for (i in seq(1870, 1920, by=5)) {
  db$sample = ifelse(db[,c("year")] == i  & db$mainsample == 1, 1, 0)
}

## A tibble: 6 x 3
#year mainsample sample
#<dbl>      <int>  <dbl>
#1  1870          1      0 ----> 1
#2  1871          1      0
#3  1872          1      0
#4  1873          1      0
#5  1874          1      0
#6  1875          1      0 ----> 1

Upvotes: 1

Views: 39

Answers (1)

akrun
akrun

Reputation: 887148

We may need either $ or [[ as [. In addition, the sample column is getting updated in each iteration. We need to store the output and Reduce it

v1 <- seq(1870, 1920, by = 5)
out <- vector("list", length(v1))

for(i in seq_along(v1)) 
   out[[i]] <- ifelse(db[["year"]] == v1[i]  & db$mainsample == 1, 1, 0)
db$sample <- +(Reduce(`|`, out))

Or this can be avoided by doing another condition

db$sample <- 0
for(i in seq(1870, 1920, by = 5) ){
   db$sample <- ifelse((db$year == i & db$mainsample)|db$sample == 1, 1, 0)
}

-output

> subset(db, year %in% seq(1870, 1920, by = 5))
# A tibble: 11 × 3
#year mainsample sample
#<dbl>      <int>  <dbl>
#1  1870          1      1
#2  1875          1      1
#3  1880          1      1
#4  1885          1      1
#5  1890          1      1
#6  1895          1      1
#7  1900          0      0
#8  1905          1      1
#9  1910          1      1
#10 1915         1      1
#11 1920         1      1

Or use %in% without a for loop

db$sample <- ifelse(db$year %in% seq(1870, 1920, by = 5)  &
        db$mainsample == 1, 1, 0)

The ifelse is not required as we could coerce the logical to binary (TRUE -> 1 and FALSE -> 0)

db$sample <- with(db, +(year %in% seq(1870, 1920, by = 5) & mainsample == 1))

Upvotes: 2

Related Questions