Как редактировать столбцы в R?

У меня есть переменная с именем name, я хочу установить ее как имена столбцов моей матрицы, но перед этим мне нужно изменить имена внутри моей переменной под названием name >

>name
[722] "TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt"
[723] "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt"
[724] "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt"

Я хочу просто сохранить буквы до четвертого -

Ожидаемый результат:

>name
 [722] "TCGA-OL-A66N-01A"
 [723] "TCGA-OL-A66O-01A"
 [724] "TCGA-OL-A66P-01A"

кто-нибудь поможет мне реализовать это в R?

5 ответов

Если размер изменяется/не гарантируется nchar, вы можете использовать str_split_fixed() от stringr.

stringr Решение:

library(stringr)
name <- c(
 "TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt",
 "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt",
 "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt")
apply(str_split_fixed(name,"-",5)[,1:4],1,paste0,collapse="-")

предоставит вам то, что вы:

## "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

Объяснение:

  • str_split_fixed(name,"-",5)

разбивает каждый векторный элемент name на 5 фигуры в соответствии с первыми 5 ocurences -

  • [,1:4]

сохранить первые 4 части (столбцы результирующей матрицы) для каждого элемента name

  • apply(...,1,paste0,collapse="-")

вставьте их вместе, свернув с помощью "-", чтобы восстановить имена (обрезать)

но что, если у меня много имен?

Здесь я сравниваю метод stringr + apply() с методом @BondedDust grep и базовым методом strsplit.

Во-первых, пусть он поднимется до 10 тысяч имен:

name <- rep(name,3.334e3)

то микропредметка:

microbenchmark(
 stringr_apply = apply(str_split_fixed(name,"-",5)[,1:4],1,paste0,collapse="-"),
 grep_ninja = sub("^([^-]*[-][^-]*[-][^-]*[-][^-]*)([-].*$)", "\\1", name),
 strsplit = sapply( lapply( strsplit(name, "\\-"), "[", 1:4), paste, collapse="-"), 
 times=25)

и получим:

# Unit: milliseconds
# expr min lq median uq max neval
# stringr_apply 845.44542 874.5674 899.27849 941.22628 976.88903 25
# grep_ninja 25.51796 25.7066 25.85404 25.95922 27.89165 25
# strsplit 115.10626 123.2645 126.45171 130.10334 147.39517 25

похоже, что base соответствие/замена шаблонов будет лучше масштабироваться... примерно на секунду здесь или на 30 раз быстрее, чем самый медленный путь.


Оператор regex "[" определяет класс символов, а в классе символов оператор "^" в первой позиции делает отрицание;

?regex
?sub
sub("^([^-]*[-][^-]*[-][^-]*[-][^-]*)([-].*$)", "\\1", name)
[1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

Это было бы проще (IMO), чем метод str_split

sapply( lapply( strsplit(name, "\\-"), "[", 1:4), 
 # extracted the first 4 elements from each list element returned by strsplit
 paste, collapse="-") # 'collapse' needed rather than 'sep'
#[1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"


Я думаю, вы, вероятно, хотите substr:

names <- substr(names,start=1,stop=16)
colnames(myDF) <- names

Это перезаписывает исходный names с указанной вами подстрокой. Где names - ваша переменная имен, start - первый символ, а stop - последний символ. Затем вы перезаписываете имена кодов вашего файла data.frame или что-то еще с names.


Если весь пятый набор буквенно-цифровых символов заканчивается на R,

> txt <- c("TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt",
 "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt",
 "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt")
> gsub("-[0-9]{2}R.*", "", txt)
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

или если тот же кусок всегда начинается с 1, но не заканчивается на R.

> gsub("-[1-9]{2}[A-Z]{1}.*", "", txt)

Вы также можете использовать регулярное выражение в strsplit, которое я не видел в других ответах.

> unlist(strsplit(txt, "-[1-9]{2}[A-Z].*"))
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

Я ищу хороший шаблон, чтобы избежать написания чрезмерно длинного, запутанного регулярного выражения.


Другая опция с пакетом stringr (хотя все еще намного медленнее, чем @BondedDust ответ):

library('stringr')
str_match(name, "^([^-]*[-][^-]*[-][^-]*[-][^-]*)")[, 1]

licensed under cc by-sa 3.0 with attribution.