Ecco una variazione di suggestione @ di thela, se non ti dispiace un approccio multi-line:
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"
In alternativa, se non ti dispiace usare un pacchetto, guarda il pacchetto "stringi", in particolare stri_flatten
, come suggerito da @Jota.
Ecco un confronto delle prestazioni:
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
Nota: L'efficienza relativa di questo approccio dipenderà da quanti elementi di una lista stanno per avere length(x) > 1
. Se la maggior parte di loro sarà comunque > 1
, allora segui l'approccio di @ 42-s. stri_flatten
migliora solo le prestazioni se si dispone di vettori di caratteri lunghi da incollare insieme come nella lista di campioni utilizzata per il benchmark sopra, altrimenti non aiuta.
'vapply'? In questo caso, 'sapply' è lento? – A5C1D2H2I1M1N2O1R2T1
Applicare solo "incolla" alle parti di "l" che sono "lunghezza> 1", quindi "non elencato"? E sostituisci 'sapply' con' vapply' mentre Ananda suggerisce di fare un po 'più di velocità. – thelatemail