Homap
Homap

Reputation: 2214

Create a vector in a loop for every pair of samples

I do a pairwise calculation between my samples and I want every pairwise calculation to be stored in a separate vector. For 3 comparisons, I have:

sample_12 <- vector(mode="numeric", length = 10)
sample_13 <- vector(mode="numeric", length = 10)
sample_23 <- vector(mode="numeric", length = 10)

Is there a possibility to create these vectors with the corresponding names in a loop so it can work for any given number of samples?

I tried the following code but I can't access the vectors outside the for-loop, how could I solve this issue?

pop = 3
sample = vector(mode="numeric", length = 10)
for (i in 1:(pop - 1)) {
  for (j in (i + 1):pop) {
    name <- paste("sample",i,j, sep = "")
    name <- vector(mode="numeric", length = 10)
  }
}

Upvotes: 0

Views: 77

Answers (3)

Gregor Thomas
Gregor Thomas

Reputation: 146144

Use a list:

pop = 3
combinations = apply(combn(pop, m = 2), 2, paste, collapse = "_")

sample = replicate(n = length(combinations), numeric(10), simplify = FALSE)
names(sample) = combinations

sample
# $`1_2`
#  [1] 0 0 0 0 0 0 0 0 0 0
# 
# $`1_3`
#  [1] 0 0 0 0 0 0 0 0 0 0
# 
# $`2_3`
#  [1] 0 0 0 0 0 0 0 0 0 0

You can then access each element of the list, e.g., sample[["1_3"]]. This scales up very easily and doesn't require pasting together names and using assign and get, which is just asking for hard-to-find bugs. You can use lapply or for loops to iterate over each item in the list trivially. Depending on your use case, it might make more sense to use the default simplify = TRUE inside replicate and keep it as a matrix or data frame. The only reason to use a list would be if some of the vectors needed to be different lengths.

Upvotes: 1

ani
ani

Reputation: 173

You can use the "assign" function:

pop = 3
sample = vector(mode="numeric", length = 10)
pop_combos <- combn(pop, 2)
for (i in 1:ncol(pop_combos)) {
    name <- paste("sample_",
                  pop_combos[,i][1],
                  pop_combos[,i][2],
                  sep="")
    assign(name, sample)
}

Outside the loop you can now access the vectors:

> sample_12
[1] 0 0 0 0 0 0 0 0 0 0

Upvotes: 1

Homunculus
Homunculus

Reputation: 359

Is something like this you are searching for?

Please suppose that you save all the vectors as rows/columns in a data.frame

list.values <- list()
col <- ncol(df)
row <- nrow(df)
for( i in 1:(col*row)) {list[[i]] = df - df[i/row,i%%col]} 

Now you have access to all the data frames in the list[[i * j]], that are the difference between all the elements and the element[i,j].

E.g: You want to access the values that are made between all the dataframe and the
element [2, 3]. Then, you do this View(list[[2*3]])

Upvotes: 0

Related Questions