This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Replace matrix row values with a shorter vector and fill other cells with 0s

Hello to everyone!

I want to combine all samples (with different rows and columns) into one matrix, but when I'm trying to assign samples to empty combined matrix I have gotten this error:

"error number of items to replace is not a multiple of replacement length"

I was wondering can I add zeros to other samples to avoid this error.

Can you help me with how to proceed?

Here the code that I wrote:

# unique taxa of all data
all.genus <- c("taxa1","taxa2","taxa3","taxa4",
               "taxa5","taxa6","taxa7","taxa8") 

# unique samples of all data
all.samples <- c("sample1.1", "sample1.2", "sample1.3","sample2.1","sample2.2","sample2.3",
                 "sample3.1","sample3.2") 

# creating matrix which containing all unique samples and taxa
combined.data = matrix(0, nrow = 8, ncol = 8)
rownames(combined.data) = all.genus
colnames(combined.data) = all.samples

# real sample1 which containing "sample1.1","sample1.2", "sample1.3"
sample1 <- matrix(runif(12), nrow = 4, ncol = 3)
colnames(sample1) = c("sample1.1", "sample1.2", "sample1.3")
rownames(sample1) = c("taxa1","taxa4","taxa5","taxa7")

# loop for assingn sample1data to combined.data
for(i in all.genus) {
  ind = which(rownames(sample1) == i)
  replace.data <- sample1[ind,]
  combined.data[i,] = replace.data
}
r

Do you have multiple samples (i.e. other data such as sample1) you want to add to your combined matrix, or just that one?

Yes, I have all 3 samples. The combined.data consist of all unique taxa and samples from that 3 samples.

2 answers

library("tidyverse")

combined_data <-
  list(sample1, sample2, sample3) |>
  map(\(x) x |> as_tibble(rownames="genus") |> pivot_longer(!genus)) |>
  bind_rows() |>
  complete(name=all.samples, genus=all.genus, fill=list(value=0)) |>
  pivot_wider(names_from=name, values_from=value) |>
  column_to_rownames("genus") |>
  as.matrix()

Many thanks for your help.

Ensure all names exist in the target matrix, then assign by matching names:

#check names
all(rownames(sample1) %in% rownames(combined.data))
# [1] TRUE
all(colnames(sample1) %in% colnames(combined.data))
# [1] TRUE

#then assign
combined.data[ rownames(sample1), colnames(sample1) ] <- sample1

# > combined.data
#        sample1.1 sample1.2  sample1.3 sample2.1 sample2.2 sample2.3 sample3.1 sample3.2
# taxa1 0.03441199 0.7566632 0.28442519         0         0         0         0         0
# taxa2 0.00000000 0.0000000 0.00000000         0         0         0         0         0
# taxa3 0.00000000 0.0000000 0.00000000         0         0         0         0         0
# taxa4 0.25604726 0.3143593 0.05609607         0         0         0         0         0
# taxa5 0.75765855 0.7226423 0.69068999         0         0         0         0         0
# taxa6 0.00000000 0.0000000 0.00000000         0         0         0         0         0
# taxa7 0.79785799 0.8926158 0.42568175         0         0         0         0         0
# taxa8 0.00000000 0.0000000 0.00000000         0         0         0         0         0

Log in to answer this question.