0
$\begingroup$

I have a very big matrix like

> head(mat[1:4,1:4])
                     Tumor_Sample_Barcode Chromosome Start_Position End_Position
1: LP6005334-DNA_H01_vs_LP6005333-DNA_H01       chr1        1026918      1026918
2: LP6005334-DNA_H01_vs_LP6005333-DNA_H01       chr1       15772155     15772155
3: LP6005334-DNA_H01_vs_LP6005333-DNA_H01       chr1       16054813     16054813
4: LP6005334-DNA_H01_vs_LP6005333-DNA_H01       chr1       24120222     24120222

> dim(mat)
[1] 450754     53
>

In Tumor_Sample_Barcode column I have the name of samples so that

> unique(mat$Tumor_Sample_Barcode)
 [1] "LP6005334-DNA_H01_vs_LP6005333-DNA_H01"     "LP6005500-DNA_D03_vs_LP6005499-DNA_D03"    
 [3] "LP6005935-DNA_G02_vs_LP6005979-DNA_C01"     "LP6007600_vs_LP6007599"                    
 [5] "LP6008202-DNA_B03_vs_LP6008201-DNA_B03"     "LP6008269-DNA_F06_vs_LP6008268-DNA_G06"    
 [7] "LP6008334-DNA_A03_vs_LP6008335-DNA_E02"     "LP6008334-DNA_A04_vs_LP6008335-DNA_E03"    
 [9] "LP6008334-DNA_B02_vs_LP6008335-DNA_F01"     "LP6008334-DNA_C02_vs_LP6008335-DNA_G01"    
[11] "LP6008334-DNA_D02_vs_LP6008335-DNA_H01"     "LP6008336-DNA_F02_vs_LP6008333-DNA_F02"    
[13] "LP6008336-DNA_G01_vs_LP6008333-DNA_G01"     "LP6008336-DNA_H01_vs_LP6008333-DNA_H01"    
[15] "LP6008336-DNA_H02_vs_LP6008333-DNA_H02"     "LP6008337-DNA_A07_vs_LP6008338-DNA_E06"    
[17] "LP6008337-DNA_H06_vs_LP6008338-DNA_D06"     "LP6008460-DNA_A04_vs_LP6008340-DNA_D05__pv"
[19] "LP6008460-DNA_D01_vs_LP6008340-DNA_E02__pv" "LP6008460-DNA_F02_vs_LP6008340-DNA_E05"    
[21] "LP6008460-DNA_G03_vs_LP6008340-DNA_C05__pv"
>

I want to change the name of these samples to A1... A21 but I don't know how

Can you help?

Thank you

$\endgroup$
2
  • 2
    $\begingroup$ Columns cannot be accessed from matrices using the dollar sign scheme e.g. df$colname. It's likely your data is a dataframe rather than a matrix. You can check with str(mat). $\endgroup$ Dec 9, 2019 at 18:47
  • $\begingroup$ Related post bioinformatics.stackexchange.com/q/10960/131 $\endgroup$
    – zx8754
    Jan 8, 2020 at 11:08

3 Answers 3

3
$\begingroup$

If your data is in a dataframe you can make use of plyr. Using mapvalues() from this library, you can rename provide a list of keys and a list of values. Instead of explicitly listing the keys, we can just use unique(mat$Tumor_Sample_Barcode) [credit to @dc37]. I use the paste0 function here and the colon operator to generate the vector of A1,A2,...,A21.

Assign the vector produced by mapvalues() to the column and you're off!

install.packages("plyr")
mat$Tumor_Sample_Barcode <-
plyr::mapvalues(x=mat$Tumor_Sample_Barcode,
                from=unique(mat$Tumor_Sample_Barcode),
                to=paste0("A", 1:21))

I'd recommend keeping this column and adding a new column with your simplified sample names, but this is not what you requested.

$\endgroup$
4
  • 2
    $\begingroup$ Nice solution, i'm not that familiar with plyr. Just a quick question, can you replace the current part of from =c(... by from = levels(mat$Tumor_Sample_Barcode) ? $\endgroup$
    – dc37
    Dec 9, 2019 at 19:06
  • 1
    $\begingroup$ Nice improvement! levels() will only work if the vector is a factor, so a more universal solution would be to replace it with from=unique(mat$Tumor_Sample_Barcode). I've update my answer to include this. $\endgroup$ Dec 9, 2019 at 19:10
  • 2
    $\begingroup$ Good to know ;) Thanks for sharing this solution using plyr $\endgroup$
    – dc37
    Dec 9, 2019 at 19:50
  • $\begingroup$ No need for extra packages (mapvalues, aka forloop), see my answer. $\endgroup$
    – zx8754
    Jan 8, 2020 at 10:52
2
$\begingroup$

Change to factor then to numeric:

mat$Tumor_Sample_Barcode <- as.numeric(as.factor(mat$Tumor_Sample_Barcode))

Using @dc37 example data:

as.numeric(as.factor(df$vect))
# [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4

If we need to prefix with "A"

paste0("A", as.numeric(as.factor(df$vect)))
# [1] "A1" "A2" "A3" "A4" "A1" "A2" "A3" "A4" "A1" "A2" "A3" "A4" "A1" "A2" "A3" "A4" "A1" "A2" "A3" "A4"

Or we can keep them as factors:

x <- sort(unique(df$vect))
factor(df$vect, levels = x, labels = paste0("A", seq_along(x)))
# [1] A1 A2 A3 A4 A1 A2 A3 A4 A1 A2 A3 A4 A1 A2 A3 A4 A1 A2 A3 A4
# Levels: A1 A2 A3 A4
$\endgroup$
1
$\begingroup$

Using sub in base R, you can:

1) define the replacement vector:

vector = paste0("A",seq(1:21))

2) and loop over each levels of your first columns to replace them individually:

for(i in 1:length(levels(mat$Tumor_Sample_Barcode)))
{
  levels(mat$Tumor_Sample_Barcode)[i] = sub(levels(mat$Tumor_Sample_Barcode)[i],vector[i], levels(mat$Tumor_Sample_Barcode)[i])
}

Example:

Here, a small example to show you:

df = data.frame(vect = factor(rep(c("a","b","c","d"),5)),
                       value = rnorm(20))

> head(df)       
  vect        value
1    a  0.418186287
2    b -0.232936122
3    c  1.563349091
4    d -0.001453912
5    a -0.453995163
6    b -0.481360070
vector = paste0("A",seq(1,4))
for(i in 1:length(levels(df$vect)))
{
  levels(df$vect)[i] = sub(levels(df$vect)[i],vector[i], levels(df$vect)[i]) 
}

And you get:

> head(df)
  vect        value
1   A1  0.418186287
2   A2 -0.232936122
3   A3  1.563349091
4   A4 -0.001453912
5   A1 -0.453995163
6   A2 -0.481360070

Does it answer your question ?

$\endgroup$
1
  • $\begingroup$ No need for forloops, see my answer. $\endgroup$
    – zx8754
    Jan 8, 2020 at 10:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.