# Use paste function with apply families

I am trying to assign different window sizes to my SNPs dataset to identify regions under selection.

this is the head of my data

head(snp_ids)
snp_id   chr  pos
Chr01__912    1  912
Chr01__944    1  944
Chr01__1107   1 1107
Chr01__1118   1 1118
Chr01__1146   1 1146
Chr01__1160   1 1160

class(snp_ids)
data.frame


I have chosen 4 different window sizes, win_size <- c(15000, 30000, 50000, 100000). I have assigned each of these different window sizes to my snp_ids dataset to identify how many SNPs are distributed within each window by looping through each window size

for (i in 1:length(win_size)){
windows <- sapply(snp_ids$pos, function(x) (ceiling(x/win_size[i]))) }  • I would like to help, but do not completely follow. I am not sure what you're trying to do. Furthermore, if you want help with code, you should provide a minimal data set to work with (for us to test it). – benn Nov 20 '17 at 20:07 • How are you getting 1.2 for window_30000? Nov 21 '17 at 8:27 • @Anna To help others you can post your own answer to the question. But please do not include it in the question body (unless they are unsuccessful attempts) – llrs Nov 30 '17 at 8:49 ## 2 Answers Not clear what we are trying to do, but here is the solution using lapply that should replicate your existing forloop. # example input data snp_ids <- read.table(text = " snp_id chr pos Chr01__912 1 912 Chr01__944 1 944 Chr01__1107 1 1107 Chr01__1118 1 1118 Chr01__1146 1 1146 Chr01__1160 1 1160", header = TRUE) # window sizes to loop through win_size <- c(15000, 30000, 50000, 100000) res <- cbind(snp_ids, data.frame( lapply(setNames(win_size, paste("window", win_size, sep = "_")), function(w) as.numeric(paste(snp_ids$chr, ceiling(snp_ids$pos/w), sep = ".")) ))) # result res # snp_id chr pos window_15000 window_30000 window_50000 window_1e.05 # 1 Chr01__912 1 912 1.1 1.1 1.1 1.1 # 2 Chr01__944 1 944 1.1 1.1 1.1 1.1 # 3 Chr01__1107 1 1107 1.1 1.1 1.1 1.1 # 4 Chr01__1118 1 1118 1.1 1.1 1.1 1.1 # 5 Chr01__1146 1 1146 1.1 1.1 1.1 1.1 # 6 Chr01__1160 1 1160 1.1 1.1 1.1 1.1  Edit: If we really want to use forloop, then try below: for (i in win_size){ windows <- ceiling(snp_ids$pos/i)
snp_ids[, paste0("window_", i)] <- as.numeric(paste(snp_ids\$chr, windows, sep = "."))
}

• thanks so much @zx8754. I have edited my post a bit and hope it is more understandable. Your code worked for me. But, as I am learning R programming I wanted to know is there any other way that I could fix my own code above? Thanks so much for your help. Nov 21 '17 at 20:12
• @Anna1364 See edit, yes we could use forloop but I prefer apply family. Nov 21 '17 at 21:43

This explicitly doesn't use apply() or lapply(), but rather the dplyr package. This is probably easier to read and debug:

library("dplyr")
snp_ids %>% mutate(window_15000=as.numeric(paste(chr, ceiling(pos/15000), sep=".")),
window_30000=as.numeric(paste(chr, ceiling(pos/30000), sep=".")),
window_50000=as.numeric(paste(chr, ceiling(pos/50000), sep=".")),
window_100000=as.numeric(paste(chr, ceiling(pos/100000), sep=".")))

• This is a bit manual, don't you think? Nov 21 '17 at 11:24
• Manual and clear is easier to debug and understand 6 months later (one could also put most of that in a function to make it shorter). Nov 21 '17 at 11:26
• Of course, personal preferences. But if there were 100 windows, that change by 500 bases for each window in 6 month time. Nov 21 '17 at 11:45
• Manual isn’t the problem — having duplication is. If I had to write this code, five times out of ten (at least!) I’d make a typo in at least one of the numbers, leading to mismatches between the column names and their actual values. That’s why we automate. (I’m saying “I” but what I really mean is “the average, competent programmer”; this class of mistakes is incredibly common). Nov 22 '17 at 16:24
• A couple lines of code duplication is a nonissue. If someone neede to add a hundred columns then sure, but for three then trivial intelligibility is more useful. Nov 22 '17 at 16:45