Извлечение векторов из списка strsplit без использования цикла
Учитывая следующий вектор:
[1] "1-1694429" "2-1546669" "3-928598" "4-834486" "5-802353" "6-659439" "7-552850"
"8-516804" "9-364061"
[10] "10-354181" "11-335154" "12-257915" "13-251310" "14-232313" "15-217628" "16-216569"
Я пытаюсь сгенерировать два вектора, каждый из которых содержит значения, полученные путем разбиения каждого элемента вектора на разделитель "-".
Я использовал:
f <- function(s) strsplit(s, "-")
cc<-sapply(names.reads, f)
голова (куб.см) $ 1-1694429
[1] "1" "1694429"
$`2-1546669`
[1] "2" "1546669"
Я знаю, что могу получить к ним доступ, например:
> cc[[1]][1]
[1] "1"
> cc[[1]][2]
[1] "1694429"
Я хотел бы иметь два вектора, каждый из которых содержит значения, хранящиеся в cc[[i]][1]
и cc[[i]][2]
... Могу ли я сделать это без использования цикла? (У меня более 1 миллиона элементов)
Ответы
Ответ 1
Используя предложение математика. coffee, следующий код избегает циклов или sapply
names.reads <- c("1-1694429", "2-1546669", "3-928598", "4-834486", "5-802353",
"6-659439", "7-552850", "8-516804", "9-364061", "10-354181",
"11-335154", "12-257915", "13-251310", "14-232313", "15-217628",
"16-216569")
cc <- strsplit(names.reads,'-')
part1 <- unlist(cc)[2*(1:length(names.reads))-1]
part2 <- unlist(cc)[2*(1:length(names.reads)) ]
производит
> part1
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15"
[16] "16"
> part2
[1] "1694429" "1546669" "928598" "834486" "802353" "659439" "552850"
[8] "516804" "364061" "354181" "335154" "257915" "251310" "232313"
[15] "217628" "216569"
хотя для этого требуется, чтобы каждое исходное значение находилось в ожидаемом формате.
Ответ 2
Другой подход:
names.reads <- c("1-1694429", "2-1546669", "3-928598", "4-834486", "5-802353",
"6-659439", "7-552850", "8-516804", "9-364061", "10-354181",
"11-335154", "12-257915", "13-251310", "14-232313", "15-217628",
"16-216569")
library(reshape2)
colsplit(string=names.reads, pattern="-", names=c("Part1", "Part2"))
Part1 Part2
1 1 1694429
2 2 1546669
3 3 928598
4 4 834486
5 5 802353
6 6 659439
7 7 552850
8 8 516804
9 9 364061
10 10 354181
11 11 335154
12 12 257915
13 13 251310
14 14 232313
15 15 217628
16 16 216569
Ответ 3
Используя sapply()
(для полноты):
y <- c("1-1694429", "2-1546669", "3-928598", "4-834486", "5-802353", "6-659439", "7-552850", "8-516804", "9-364061",
"10-354181", "11-335154", "12-257915", "13-251310", "14-232313", "15-217628", "16-216569")
x <- sapply(y, function(x) strsplit(x, "-")[[1]])
a <- x[1,]
b <- x[2,]
Если вам не нужны имена в результате, в качестве sapply()
, вы можете установить их в NULL:
names(a) <- NULL
Ответ 4
Глядя на решение подобной проблемы, наткнулся на этот пост. Добавляя мое решение к этому, хотя я далеко вперед в будущем! (копирование с Генри кодом)
names.reads <- c("1-1694429", "2-1546669", "3-928598", "4-834486", "5-802353",
"6-659439", "7-552850", "8-516804", "9-364061", "10-354181",
"11-335154", "12-257915", "13-251310", "14-232313", "15-217628",
"16-216569")
require(plyr)
cc <- ldply(strsplit(names.reads, '-'))
cc$V1;cc$V2
Это создает кадр данных, из которого могут быть извлечены векторы, относящиеся к n-му элементу каждого элемента в списке.
Ответ 5
Или с пакетом purrr
:
Часть 1:
> map(strsplit(names.reads, "-"), ~.x[1]) %>% unlist()
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13"
[14] "14" "15" "16"
Часть 2:
> map(strsplit(names.reads, "-"), ~.x[2]) %>% unlist()
[1] "1694429" "1546669" "928598" "834486" "802353" "659439"
[7] "552850" "516804" "364061" "354181" "335154" "257915"
[13] "251310" "232313" "217628" "216569"