2013-04-10 4 views
1

J'ai une liste avec 138 tables dans (prop.table). Chaque table peut contenir jusqu'à 20 variables (catégories numériques allant de 11 à 95 sous la forme de colnames). J'ai besoin de convertir cette liste à une base de données principale. Les trois premiers tableaux ressemblent à ceci:Listes à Dataframes avec NA ou 0

[[1]] 
x 
     21   41   42   43   52   71   81   82 
0.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 

[[2]] 
x 
     21   41   42   43   52   71   90 
0.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 

[[3]] 
x 
     21   22   23   41   42 
0.043254082 0.008307075 0.016614151 0.930392438 0.001432254 

J'ai besoin de convertir en une matrice de sorte qu'il ressemble à ceci, avec NAs ou 0 lorsque la variable catégorielle n'est pas disponible:

x<-matrix (nrow=3, ncol=11) 
colnames(x) <-c('21', '22', '23', '41', '42', '43', '52', '71', '81', '82', '90') 

Je essayé d'utiliser cette ligne d'une précédente question similaire, mais la table est incorrect:

df <- data.frame(matrix(unlist(prop.table), nrow=138, byrow=T)) 

Toutes les suggestions sur la façon de résoudre ce problème et d'obtenir la table je besoin?

Répondre

1

Voici de façon simple à utiliser lapply, rbind et do.call

ptl 
## [[1]] 
## x 
##   21   41   42   43   52   71   81   82 
## 0.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 
## 
## [[2]] 
## x 
##   21   41   42   43   52   71   90 
## 0.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 
## 
## [[3]] 
## x 
##   21   22   23   41   42 
## 0.043254082 0.008307075 0.016614151 0.930392438 0.001432254 
## 
## [[4]] 
## x 
##   21   22   31   41   42   43   81 
## 0.10028653 0.03123209 0.00487106 0.66103152 0.03037249 0.01604585 0.15616046 
## 
## [[5]] 
## x 
##   21   41   42   43   81 
## 0.0662080825 0.8291774147 0.0005732302 0.0865577529 0.0174835196 
## 
## [[6]] 
## x 
##   21   22   31   41   42   43   81 
## 0.081948424 0.002292264 0.006303725 0.825501433 0.029226361 0.020630372 0.034097421 
## 


# Get unique names of all columns in tables in the list 
resCol <- unique(unlist(lapply(ptl, names))) 

# Get dimensions of desired result 
nresCol <- length(resCol) 
nresRow <- length(ptl) 

# Create 'Template' data.frame row 
DF <- as.data.frame(matrix(rep(0, nresCol), nrow = 1, dimnames = list(1, resCol))) 

# for every table in list, create copy of DF, fill it appropriately, then rbind result together using do.call 

result <- do.call(rbind, lapply(ptl, function(x) { 
    retDF <- DF 
    retDF[, names(x)] <- x 
    return(retDF) 
})) 

# rename rows(optional) 
rownames(result) <- 1:nrow(result) 

result 
##   21  41   42   43   52   71   81   82  90   22   23   31 
## 1 0.02007456 0.5815888 0.2248351018 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 0.0000000 0.000000000 0.00000000 0.000000000 
## 2 0.01175122 0.3697334 0.3410719404 0.03066781 0.08655775 0.01633706 0.00000000 0.00000000 0.1438808 0.000000000 0.00000000 0.000000000 
## 3 0.04325408 0.9303924 0.0014322544 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.0000000 0.008307075 0.01661415 0.000000000 
## 4 0.10028653 0.6610315 0.0303724928 0.01604585 0.00000000 0.00000000 0.15616046 0.00000000 0.0000000 0.031232092 0.00000000 0.004871060 
## 5 0.06620808 0.8291774 0.0005732302 0.08655775 0.00000000 0.00000000 0.01748352 0.00000000 0.0000000 0.000000000 0.00000000 0.000000000 
## 6 0.08194842 0.8255014 0.0292263610 0.02063037 0.00000000 0.00000000 0.03409742 0.00000000 0.0000000 0.002292264 0.00000000 0.006303725 
2

Est-ce que c'est ce que vous voulez?

x1 <- c(1, 5, 7) 
names(x1) <- 1:3 
x2 <- c(1, 2, 7) 
names(x2) <- c(1,3,5) 
l <- list(x1, x2) 

m <- matrix(nrow=length(l), ncol=5) 
colnames(m) <- 1:5 
for (i in 1:length(l)) { 
    m[i, names(l[[i]])] <- l[[i]] 
} 

Peut-être que l'on peut remplacer la boucle avec une fonction apply, mais je ne sais pas ... En fait, je boucle la liste et mettre dans chaque ligne de la matrice les colonnes qui correspondent aux noms de le vecteur dans la liste. Désolé pour ne pas utiliser votre ensemble de données, mais vous n'aviez pas le code à portée de main et j'étais trop paresseux pour le taper dehors.

+0

merci pour la réponse rapide. Cela ne semble pas fonctionner. Peut-être parce que mon objet 'prop.table' est une liste avec 138 tables différentes dedans. Au départ, je pensais que c'était une liste de 138 listes, mais il s'avère que ce sont des tableaux. –

+0

Ce bit fonctionnera bien pour les listes de listes. Merci! –

1

Je vais simplement suggérer une solution. Que diriez-vous juste concaténer toutes les listes en une. Donc, vous auriez

MyDataFrame 
variable1   1   1   1   1   1   1   1   1 
variable2  21   41   42   43   52   71   81   82 
variable30.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 

variable1   2   2   2   2   2   2   2 
variable2  21   41   42   43   52   71   90 
variable30.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 

variable1   3   3   3   3   3 
variable2   21   22   23   41   42 
variable30.043254082 0.008307075 0.016614151 0.930392438 0.001432254 

Et une fois que vous avez une seule trame de données. Vous pouvez utiliser la fonction de remodelage. comme

install.packages('reshape') 
library('reshape') 
cast(MyDataFrame, variable1~variable2) 
1

Ce ne sera pas le plus efficace, mais en utilisant plyr et reshape2, et en supposant que votre liste des prop.tables est appelée foo

library(plyr) 
library(reshape2) 


allData <- dcast(ldply(lapply(seq_along(foo), function(x) data.frame(foo[[x]], id = x))), 
       id ~ x, value.var = 'Freq') 

ou plus avant droit

ff <- c('21', '22', '23', '41', '42', '43', '52', '71', '81', '82', '90') 

t(sapply(foo, function(x,y) {x[ff]})) 
+0

merci pour la réponse rapide. Cela ne semble pas fonctionner. Peut-être parce que mon objet 'prop.table' est une liste avec 138 tables différentes dedans. Au départ, je pensais que c'était une liste de 138 listes, mais il s'avère que ce sont des tableaux. –

+0

@IDelToro - rend votre question reproductible en incluant 'dput (head (prop.table.list))' (où 'prop.table.list' est votre liste de tables de prop – mnel

+0

' prop.table.list <-lapply (Landcover, fonction (x) prop.table (table (x))) dput (head (prop.table.list)) ' –

2

rbind.fill du paquet plyr fera exactement cela pour vous:

# make an example `prop.table`: 
tbl <- 1:10 
names(tbl) <- letters[1:10] 
tbl <- as.matrix(tbl) 

# make sure some of the columns are missing 
prop.table <- list(tbl[sample(10, size=8),], tbl[sample(10, size=7),], tbl[sample(10, size=9),]) 
# [[1]] 
# d b g c h f e i 
# 4 2 7 3 8 6 5 9 
# [[2]] 
# h g d a j f c 
# 8 7 4 1 10 6 3 
# [[3]] 
# c i b d j a h g e 
# 3 9 2 4 10 1 8 7 5 

Vous pouvez utiliser la fonction rbind.fill de plyr, qui est juste rbind mais il remplit les colonnes manquantes avec NA.Il peut prendre dans une liste de trames de données à rbind ensemble, donc je convertir chaque élément de prop.table en dataframe premier (nécessaire le t pour garantir que chaque prop.table[[i]] a été traitée comme une ligne, pas une colonne)

rbind.fill(lapply(prop.table, function (x) as.data.frame(t(x)))) 
# d b g c h f e i a j 
# 1 4 2 7 3 8 6 5 9 NA NA 
# 2 4 NA 7 3 8 6 NA NA 1 10 
# 3 4 2 7 3 8 NA 5 9 1 10 

(Remarque - vous pouvez trier les colonnes du dataframe de sortie avec x[, order(colnames(x))])

Questions connexes