Problem getting this simple For loop correctly

This simple for loop I want it to run the function FindMarkers, which will take as an argument a data identifier (1,2,3 etc..) that it will use to pull data from. I then want it to store the result of the function in immunes.i, where I want I to be the same integer (1,2,3)

So I want an output of 15 files names immunes.0, immunes.1, immunes.2 etc...
I've ran the code before, and it runs, but doesn't make the individual files. It just makes 1 file at the end called, not surprisingly immunes.i

Right now Im getting a different error though; here is the code:

for (i in 0:14){
    Idents(AllCells.combined) <- AllCells.combined$seurat_clusters
    DefaultAssay(AllCells.combined) <- "RNA"
    immunes.i <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", verbose = TRUE, group.by="stim", subset.ident = "i")
}

The error i get is

Error in WhichCells.Seurat(object = x, cells = cells, idents = idents,  : 
  Cannot find the following identities in the object: i

If I run the last line by itself it works perfectly, namely:
immunes.0 <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", verbose = TRUE, group.by="stim", subset.ident = "0")

any advice? thanks!

The problem is that the loop isn't interpolating your i as a variable, meaning it doesn't get translated into the loop number. You can create a concatenation of all your desired names, something like:

immunes <- c(immunes.0... immunes.14)

and then call immunes[i] <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", verbose = TRUE, group.by="stim", subset.ident = "i")

There might be easier solutions.

The thing is that I don't have immune.0, immune.1 yet... these are to be created by the loop once the function runs, so I can't put anything before then calling those, or unless I misunderstood

Ok I tried even creating them before hand and it doesn't work here is what I get:

idg.6 <- NULL
idg.7 <- NULL
idg <- c(idg.6, idg.7)

for (i in 6:7){
idg[i] <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", verbose = TRUE, group.by="stim", subset.ident = i)
}

The output was thus:
Warning messages:
1: In idg[i] <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", :
number of items to replace is not a multiple of replacement length
2: In idg[i] <- FindMarkers(AllCells.combined, ident.1 = "VEH", ident.2 = "IMQ", :
number of items to replace is not a multiple of replacement length`

There are several problems with your code, the more evident one is that your idg vector is intended to have length = 2 (although is actually empty) but you are trying to assign positions 6 and 7 and that makes no sense, also it seems like the output of FindMarkers() is not a single element that you can replace in a vector (I can't be sure since you are not providing a proper REPRoducible EXample (reprex))

I can't test if this is going to work, because of the lack of a reprex, but maybe it would point you in the right direction

for (i in 6:7){
    marker_i <- FindMarkers(AllCells.combined,
                ident.1 = "VEH",
                ident.2 = "IMQ",
                verbose = TRUE,
                group.by="stim",
                subset.ident = i)
    assign(paste0("inmunes.", i), marker_i)
}

Accually your solution worked pefectly thank you so much. I want to ask one followup if I may, I would like to write each immunes.i file to a csv each time through the loop so I dont have to type it out each time at the end of the loop. Ive tried various things I can't seem to get it. I tried variations on what you wrote and I couldn't get it either. Here is an example:

Sorry I cant seem to get the formatting correct but here it is:

for (i in 0:15){
marker_i <- FindConservedMarkers(AllCells.combined, ident.1 = i, grouping.var = "stim", verbose =TRUE)

assign(paste0("immunes.", i), marker_i)
write.csv(immunes.i, file = "immunes.", i)
}

You can see what I'm trying to do. As written I get an "object 'IL17ClusterMarker.i' not found" error. I tried the following also:

write.csv(immunes[i], file = "immunes.", i) no luck their either. any ideas?

Thanks so much

You are having the same problem as before, meaning you're not interpolating correctly. The way to do this properly is to create each object you need in the loop and assign it to an object marker_i, as the solution shows. But then, when saving it to csv, you have to use the strategy with paste0 to create the filename immunes.X and assign the temp object marker_i and save.

This is useful if you don't need the objects immunes.X to be present in the current R environment.

for (i in 0:15){
marker_i <- FindConservedMarkers(AllCells.combined, ident.1 = i, grouping.var = "stim", verbose =TRUE)
filename <- paste0("immunes.", i,".csv")
write.csv(marker_i, filename)
}

This is beautiful thank you so much. Im going to read up right now on the paste0 and assign functions so I can learn to do this on my own.

Thanks again

You're welcome. Play more with for lops and putting a lot of print statements throughout the loop, so you understand what's happening.
For example:

for (i in 0:15){
print(i) #this is the value of i at the beginning of the loop 
marker_i <- FindConservedMarkers(AllCells.combined, ident.1 = i, grouping.var = "stim", verbose =TRUE)
print(i) #this is to show that i hasn't changed
print(marker_i) # this is to show that marker_i was created (might be a huge object, so you can use print(head(marker_i)) )
filename <- paste0("immunes.", i,".csv")
print(filename) #this shows that filename was created here
print(i) # this shows that i still hasn't changed
write.csv(marker_i, filename)
}

When you run all this, you should get a bunch of numbers and filenames, but they will help you understand what happens at each step within the loop. I still make a lot of mistakes when doing loops and I have to pepper print statements all over my code to what's going on, so just keep going.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.