Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Nested for loop: problem with indexing in R

I’m struggling to get the correct index in nested for-loops in R.

Here’s an example:

# First: create function that inserts character pattern in string
  fun_insert <- function(x, pos, insert) {
    gsub(paste0("^(.{", pos, "})(.*)$"),
         paste0("\\1", insert, "\\2"),
         x)
  }

# Variables:
original_m<-c("BODYSHAME", "WBIS_M")
k<-length(original_m)
storage_mod_xm_all<-c("FEAROFSELFCOMPASSION", "SBOSS")
nmod_xm_all<-length(storage_mod_xm_all)
storage_med_pt1<-c("BODYSHAME ~ a1*","WBIS_M ~ a2*")
storage_mod_xm<-0

Now I want to use nested for-loops to get this output in the variable storage_mod_xm (a list with the following character strings):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

"BODYSHAME ~ a11*FEARSELFCOMPASSION" "WBIS_M ~ a21*FEARSELFCOMPASSION"    "BODYSHAME ~ a12*SOBBS"             
"WBIS_M ~ a22*SOBBS"

So basically the first index after a should refer to the number of element from the variable original_m and the second index should refer to the number of element from the variable storage_mod_xm_all.

How I tried to do this:

# --> M ~ a*W

if (nmod_xm_all>0){
# combine M ~ b* and x-m moderator
  storage_mod_xm_pt1<-outer(storage_med_pt1, storage_mod_xm_all, FUN = "paste0") 
  dim(storage_mod_xm_pt1)<-NULL
  n_st_mod_xm<-length(storage_mod_xm_pt1)
  # for loop over all mediators
  for (j in 1:k) {
    # for loop over all moderators
    for (i in 1:n_st_mod_xm){
      storage_mod_xm_pt2[i]<-fun_insert(storage_mod_xm_pt1[i], pos=(nchar(original_m[j])+5), insert=i) # insert different index to label
    } # end of for loop moderators
  } # end of for loop mediators
  storage_mod_xm<-paste(c(storage_mod_xm_pt2), collapse=";") #""M1 ~ a11*gender_M;M2 ~ a22*gender_M"
} # end of if-else statement 

The output I get from the variable storage_mod_xm:

"BODYSHAME ~1 a1*FEARSELFCOMPASSION" "WBIS_M ~ a22*FEARSELFCOMPASSION"    "BODYSHAME ~3 a1*SOBBS"             
[4] "WBIS_M ~ a24*SOBBS"

BUT desired output:

"BODYSHAME ~ a11*FEARSELFCOMPASSION" "WBIS_M ~ a21*FEARSELFCOMPASSION"    "BODYSHAME ~ a12*SOBBS"             
[4] "WBIS_M ~ a22*SOBBS"

Anyone a solution how to fix this?

>Solution :

I have a slightly different solution –

  • Simplified fun_insert function to a one-liner sprintf.
  • Added an additional argument in fun_insert (j) so that we can get rid of storage_med_pt1.
  • Instead of nested for loop I have used nested sapply. It works the same way.
fun_insert <- function(org, i, j, stor) sprintf('%s ~ a%i%i*%s', org, i, j, stor)

#For one value
fun_insert(original_m[1], 1, 1, storage_mod_xm_all[1])
#[1] "BODYSHAME ~ a11*FEAROFSELFCOMPASSION"

#For all of them
c(t(sapply(seq_along(original_m), function(x) {
  sapply(seq_along(storage_mod_xm_all), function(y) {
    fun_insert(original_m[x], x, y, storage_mod_xm_all[y])
  })
})))

#[1] "BODYSHAME ~ a11*FEAROFSELFCOMPASSION" "WBIS_M ~ a21*FEAROFSELFCOMPASSION" 
#[3] "BODYSHAME ~ a12*SBOSS"                "WBIS_M ~ a22*SBOSS"        
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading