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
    $\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$ – Kohl Kinning Dec 9 '19 at 18:47
  • $\begingroup$ Related post bioinformatics.stackexchange.com/q/10960/131 $\endgroup$ – zx8754 Jan 8 at 11:08
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.

| improve this answer | |
$\endgroup$
  • 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 '19 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$ – Kohl Kinning Dec 9 '19 at 19:10
  • 2
    $\begingroup$ Good to know ;) Thanks for sharing this solution using plyr $\endgroup$ – dc37 Dec 9 '19 at 19:50
  • $\begingroup$ No need for extra packages (mapvalues, aka forloop), see my answer. $\endgroup$ – zx8754 Jan 8 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
| improve this answer | |
$\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 ?

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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