当前位置:  开发笔记 > 编程语言 > 正文

将列表列表转换为字符向量

如何解决《将列表列表转换为字符向量》经验,为你挑选了2个好方法。

我有一个字符列表列表.例如:

l <- list(list("A"),list("B"),list("C","D"))

因此,您可以看到一些元素是长度> 1的列表.

我想将此列表列表转换为字符向量,但我希望长度> 1的列表在字符向量中显示为单个元素.

unlist功能并没有做到这一点,而是:

> unlist(l)
[1] "A" "B" "C" "D"

还有什么比:

sapply(l,function(x) paste(unlist(x),collapse=""))

为了得到我想要的结果:

"A"  "B"  "CD"

42-.. 19

您可以跳过取消列表步骤.您已经发现paste0需要collapse = TRUE将向量的顺序元素"绑定"在一起:

> sapply( l, paste0, collapse="")
[1] "A"  "B"  "CD"


A5C1D2H2I1M1.. 6

如果你不介意多线方法,这是@ thela建议的变体:

x <- lengths(l)                                     ## Get the lengths of each list
l[x > 1] <- lapply(l[x > 1], paste0, collapse = "") ## Paste only those together
unlist(l, use.names = FALSE)                        ## Unlist the result
# [1] "A"  "B"  "CD"

或者,如果您不介意使用软件包,请查看"stringi"软件包,具体来说stri_flatten,请按@Jota的建议.


这是一个性能比较:

l <- list(list("A"), list("B"), list("B"), list("B"), list("B"),
          list("C","D"), list("E","F", "G", "H"), 
          as.list(rep(letters,10)), as.list(rep(letters,2)))
l <- unlist(replicate(1000, l, FALSE), recursive = FALSE)

funop <- function() sapply(l,function(x) paste(unlist(x),collapse=""))
fun42 <- function() sapply(l, paste0, collapse="")
funv  <- function() vapply(l, paste0, character(1L), collapse = "")
funam <- function() {
  x <- lengths(l)
  l[x > 1] <- lapply(l[x > 1], paste0, collapse = "")
  unlist(l, use.names = FALSE)
}
funj <- function() sapply(l, stri_flatten)
funamj <- function() {
  x <- lengths(l)
  l[x > 1] <- lapply(l[x > 1], stri_flatten)
  unlist(l, use.names = FALSE)
}

library(microbenchmark)
microbenchmark(funop(), fun42(), funv(), funam(), funj(), times = 20)
# Unit: milliseconds
#      expr      min       lq     mean   median       uq      max neval   cld
#   funop() 78.21822 84.79588 85.30055 85.36399 86.90540 90.48321    20     e
#   fun42() 56.16938 57.35735 61.60008 58.04969 65.82836 81.46482    20    d 
#    funv() 54.64101 56.23245 60.07896 57.26049 63.96815 78.58043    20    d 
#   funam() 45.89760 46.89890 48.99810 47.29617 48.28764 56.92544    20   c  
#    funj() 28.73405 29.94041 32.00676 30.56711 31.11448 39.93765    20  b   
#  funamj() 18.64829 19.01328 21.05989 19.12468 19.52516 32.87569    20 a 

注意:此方法的相对效率取决于将有多少列表项length(x) > 1.如果他们中的大多数都是> 1无论如何,那么就采用@ 42-的方法. stri_flatten只有在您将长字符向量粘贴在一起时才能提高性能,就像在上面的基准测试中使用的样本列表一样,否则,它没有帮助.



1> 42-..:

您可以跳过取消列表步骤.您已经发现paste0需要collapse = TRUE将向量的顺序元素"绑定"在一起:

> sapply( l, paste0, collapse="")
[1] "A"  "B"  "CD"



2> A5C1D2H2I1M1..:

如果你不介意多线方法,这是@ thela建议的变体:

x <- lengths(l)                                     ## Get the lengths of each list
l[x > 1] <- lapply(l[x > 1], paste0, collapse = "") ## Paste only those together
unlist(l, use.names = FALSE)                        ## Unlist the result
# [1] "A"  "B"  "CD"

或者,如果您不介意使用软件包,请查看"stringi"软件包,具体来说stri_flatten,请按@Jota的建议.


这是一个性能比较:

l <- list(list("A"), list("B"), list("B"), list("B"), list("B"),
          list("C","D"), list("E","F", "G", "H"), 
          as.list(rep(letters,10)), as.list(rep(letters,2)))
l <- unlist(replicate(1000, l, FALSE), recursive = FALSE)

funop <- function() sapply(l,function(x) paste(unlist(x),collapse=""))
fun42 <- function() sapply(l, paste0, collapse="")
funv  <- function() vapply(l, paste0, character(1L), collapse = "")
funam <- function() {
  x <- lengths(l)
  l[x > 1] <- lapply(l[x > 1], paste0, collapse = "")
  unlist(l, use.names = FALSE)
}
funj <- function() sapply(l, stri_flatten)
funamj <- function() {
  x <- lengths(l)
  l[x > 1] <- lapply(l[x > 1], stri_flatten)
  unlist(l, use.names = FALSE)
}

library(microbenchmark)
microbenchmark(funop(), fun42(), funv(), funam(), funj(), times = 20)
# Unit: milliseconds
#      expr      min       lq     mean   median       uq      max neval   cld
#   funop() 78.21822 84.79588 85.30055 85.36399 86.90540 90.48321    20     e
#   fun42() 56.16938 57.35735 61.60008 58.04969 65.82836 81.46482    20    d 
#    funv() 54.64101 56.23245 60.07896 57.26049 63.96815 78.58043    20    d 
#   funam() 45.89760 46.89890 48.99810 47.29617 48.28764 56.92544    20   c  
#    funj() 28.73405 29.94041 32.00676 30.56711 31.11448 39.93765    20  b   
#  funamj() 18.64829 19.01328 21.05989 19.12468 19.52516 32.87569    20 a 

注意:此方法的相对效率取决于将有多少列表项length(x) > 1.如果他们中的大多数都是> 1无论如何,那么就采用@ 42-的方法. stri_flatten只有在您将长字符向量粘贴在一起时才能提高性能,就像在上面的基准测试中使用的样本列表一样,否则,它没有帮助.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有