web-dev-qa-db-ja.com

リストのリストを文字ベクトルに変換する

キャラクターのリストのリストがあります。例えば:

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"
11
dan

リストから外す手順はスキップできます。あなたはすでにそれを理解しましたpaste0が必要collapse = TRUEを使用して、ベクトルの連続する要素を「バインド」します。

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

複数行のアプローチを気にしない場合の@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"
_

または、パッケージを使用してもかまわない場合は、@ Jotaの提案に従って、 "stringi"パッケージ、特に_stri_flatten_を確認してください。


パフォーマンスの比較は次のとおりです。

_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_は、上記のベンチマークで使用したサンプルリストのように、長い文字ベクトルを一緒に貼り付ける場合にのみパフォーマンスを向上させます。それ以外の場合は効果がありません。