Извлечение векторов из списка strsplit без использования цикла - PullRequest
15 голосов
/ 25 января 2012

Учитывая следующий вектор:

[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 миллиона элементов)

Ответы [ 5 ]

20 голосов
/ 25 января 2012

Используя подсказку математического.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"

, хотя требует, чтобы каждое исходное значение находилось в ожидаемом формате.

7 голосов
/ 01 июня 2016

Использование 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")

Как указывалось в комментариях @Bird, параметр USE.NAMES можно использовать, чтобы избежать имен врезультирующий вектор.

x <- sapply(y, function(x) strsplit(x, "-")[[1]], USE.NAMES=FALSE)

a <- x[1,]

b <- x[2,]

6 голосов
/ 21 июня 2013

Другой подход:

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 голосов
/ 25 июля 2017

Или с пакетом 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" 
2 голосов
/ 21 июня 2013

Глядя, чтобы решить аналогичную проблему, наткнулся на этот пост.Добавляя свое решение к этому, хотя я далеко вперед в будущем!(копирует из Генри код)

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-му элементу каждого элемента в списке.

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