web-dev-qa-db-fra.com

Combinez deux listes dans une trame de données dans R

J'ai deux listes avec une structure différente:

listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)

listA
[[1]]
[1] "a" "b" "c"

[[2]]
[1] "d" "e"

listB
[[1]]
[1] 0.05

[[2]]
[1] 0.5

J'ai une idée de la façon d'utiliser le bouclage pour combiner les deux listes dans une trame de données qui ressemble à celle ci-dessous, mais je suis sûr qu'il existe un moyen plus efficace de le faire.

data.frame(A = c("a","b","c","d","e"), B = c(rep(0.05,3), rep(0.5,2)))
  A    B
1 a 0.05
2 b 0.05
3 c 0.05
4 d 0.50
5 e 0.50
15
Rami Al-Fahham

Ceci est une autre option:

do.call(rbind, Map(data.frame, A=listA, B=listB))

#   A    B
# 1 a 0.05
# 2 b 0.05
# 3 c 0.05
# 4 d 0.50
# 5 e 0.50
21
Matthew Plourde

Peut-être existe-t-il une manière plus élégante de conserver la classe numeric des éléments de list2 ... Mais celui-ci fonctionne aussi

df <- do.call(rbind,mapply(cbind, listA, listB))
df <- as.data.frame(df, stringsAsFactors = FALSE)
df[,2] <- as.numeric(df[,2])

EDIT La solution de Matthew Plourde est bien meilleure en utilisant Map aka mapply(data.frame, A=listA, B=listB, SIMPLIFY = FALSE)

3
Rentrop

Je préfère ceci:

do.call(rbind,
        Map(function(...) setNames(cbind.data.frame(...), 
                                   c("A", "B")), 
            listA, listB))
#  A    B
#1 a 0.05
#2 b 0.05
#3 c 0.05
#4 d 0.50
#5 e 0.50
2
Roland

Voici une autre façon:

do.call(rbind,
        lapply(1:length(listA),
               function(i)
                 data.frame(A=unlist(listA[i]),
                            B=unlist(listB[i]))))
1
zx8754

Une autre façon sans utiliser do.call:

cbind(data.frame(listA), data.frame(listB))
1
S.Zhong

Si vous recherchez une solution tidyverse, voici l'analogue de la réponse acceptée. L'utilisation du suffixe dfr pour la famille de fonctions map permet une solution très simple qui devrait également être plus rapide que do.call("rbind").

library(tidyverse)
listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)

map2_dfr(listA, listB, ~ tibble(A = .x, B = .y))
#> # A tibble: 5 x 2
#>   A         B
#>   <chr> <dbl>
#> 1 a      0.05
#> 2 b      0.05
#> 3 c      0.05
#> 4 d      0.5 
#> 5 e      0.5

Créé le 2019-02-12 par le package reprex (v0.2.1)

1
Calum You