Home > Net >  Incrementing over nested for loop in R if specific condition is met
Incrementing over nested for loop in R if specific condition is met

Time:03-31

I am relatively new to R and trying to create a nested for loop that will increment over a sequence of random numbers and add it to some variables in the table if a specific condition is met. Below is the sample code:

#create sample table
tab <- matrix(c(7, 5, 0, 19, 3, 1, 17, 8, 0, 7, 6, 0, 3, 1, 1), ncol=3, byrow=TRUE)
colnames(tab) <- c('V1','V2','V3')
rownames(tab) <- c('abc','def','ghi','jkl', 'mne')
tab <- as.data.frame(tab)
tab

#get random variables
n = 3
rand_num <- round(rnorm(n, mean = 3, sd = 1), digits = 0)
rand_num


#create for loop do add random variables to values where v3 = 0
tab2 <- tab
for(i in 1:nrow(tab))
{ 
  if(tab2$V3[i] == 0) 
  {
    for(p in seq(from = 1, to = 3)
    tab2$V2[i] <- tab2$V2[i]   rand_num[p]
  }
}

tab
V1 V2 V3
abc  7  5  0
def 19  3  1
ghi 17  8  0
jkl  7  6  0
mne  3  1  1

tab2
V1 V2 V3
abc  7  5  0
def 19  3  1
ghi 17  8  0
jkl  7  6  0
mne  3  1  1

However, the for loop doesn't work as expected. The expected result is below

tab2
     V1 V2 V3
abc  7  7   0
def 19  3   1
ghi 17  13  0
jkl  7  8   0
mne  3  1   1

Appreciate if anyone can point me in the right direction

CodePudding user response:

Here is a vectorized solution without for loops. I have changed the definition of n.

tab <- matrix(c(7, 5, 0, 19, 3, 1, 17, 8, 0, 7, 6, 0, 3, 1, 1), ncol=3, byrow=TRUE)
colnames(tab) <- c('V1','V2','V3')
rownames(tab) <- c('abc','def','ghi','jkl', 'mne')
tab <- as.data.frame(tab)
tab
#>     V1 V2 V3
#> abc  7  5  0
#> def 19  3  1
#> ghi 17  8  0
#> jkl  7  6  0
#> mne  3  1  1

#get random variables
set.seed(2022)
n = sum(tab$V3 == 0)
rand_num <- round(rnorm(n, mean = 3, sd = 1), digits = 0)
rand_num
#> [1] 4 2 2

tab2 <- tab
i <- which(tab2$V3 == 0)
tab2$V2[i] <- tab2$V2[i]   rand_num

Created on 2022-03-30 by the reprex package (v2.0.1)

CodePudding user response:

This line loop:

for(p in seq(from = 1, to = 3)
    tab2$V2[i] <- tab2$V2[i]   rand_num[p]

is adding the all three random numbers to each value of tab2$V2[i]

You can avoid loops all together here:

#Define a seed value to make the debugging repeatable
set.seed(1)
#generate random variables
rand_num <- round(rnorm(nrow(tab2), mean = 3, sd = 1), digits = 0)

tab2$V2 <- ifelse(tab2$V3 == 0, tab2$V2 rand_num, tab2$V3)
  • Related