【问题标题】:Extract vectors from strsplit list without using a loop从 strsplit 列表中提取向量而不使用循环
【发布时间】:2012-02-18 05:58:11
【问题描述】:

考虑以下向量:

[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)

头(cc) $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] 的值...我可以不使用循环来做到这一点吗? (我有超过 100 万个元素)

【问题讨论】:

  • 我不确定您所说的“不使用循环单独选择”是什么意思-您必须为第 i 个向量执行 cc[[i]] ...您的意思是你只想要一个包含所有字符串位的平面向量吗? (顺便说一句,你可以做cc &lt;- strsplit(names.reads,'-'),而不必使用sapply
  • @mathematical.coffee 我已经编辑了我的问题,我希望它更清楚一点..

标签: r


【解决方案1】:

使用mathical.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"

虽然它确实要求每个原始值都采用预期的格式。

【讨论】:

  • 我接受您的回答,因为 sapply 在不到我的向量大小的四分之一时失败(由于某种原因,sapply 总是这样),而且您的好解决方案更适合我。
  • 它是更快的一个,但是这个解决方案的问题是所有元素必须是以下形式:x_xxxxx 一旦你有任务之一的价值,它就不能很好地工作,因为例如:1694429 而不是:1-1694429。对于这种情况,strsplit 只会生成一个包含一个值的列表,而不是一对值。然后选择偶数和奇数索引的计算不起作用。 @MYaseen208 指出的解决方案是性能较差的解决方案,但它涵盖了这种情况。
【解决方案2】:

使用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 在 cmets 中指出的那样,USE.NAMES 参数可用于避免结果向量中出现名称。

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

a &lt;- x[1,]

b &lt;- x[2,]

【讨论】:

  • 此解决方案将其拆分两次。计算成本高
  • sappaly() 中的 USE.NAMES=FALSE 选项也会删除名称。
【解决方案3】:

另一种方法:

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

【讨论】:

  • 此解决方案也适用于非均匀数据。例如,如果你有 '1-2-3' 和 1-2',你最终会得到一个 1 和 1 的数组,以及一个 2-3 和 2 的数组。它适用于我获取顶级目录的应用程序目录中所有目录的名称。 (实际上是通过 aws.s3 的 S3 存储桶)
【解决方案4】:

或使用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" 

【讨论】:

    【解决方案5】:

    想解决类似的问题,偶然发现了这篇文章。尽管我在未来遥遥领先,但为此添加了我的解决方案! (从亨利那里复制代码)

    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 个元素有关的向量。

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 2012-10-04
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-11
      • 2014-09-20
      相关资源
      最近更新 更多