J'ai un vecteur de chaînes que je souhaite utiliser comme en-têtes de colonne pour une trame de données.

Exemple: cols <- c ("A: Ike (N = 428)", "F: Mike (N = 691)", "G: Bike (N = 380)", "Total (N = 1499)", " valeur p ")

J'ai une liste de listes de listes de chaînes que je souhaite ajouter en tant que données de mon bloc de données.

Exemple, trois premières lignes:

[[1]] [[1]]$Female [[1]]$Female[[1]] [1] "151"   "35.3%"

[[1]]$`Age in Years` [[1]]$`Age in Years`[[1]] NULL

[[1]]$`Mean (SD)` [[1]]$`Mean (SD)`[[1]] [1] "59.7" "11.4"

[[2]] [[2]]$Female [[2]]$Female[[1]] [1] "280"   "40.5%"

[[2]]$`Age in Years` [[2]]$`Age in Years`[[1]] NULL

[[2]]$`Mean (SD)` [[2]]$`Mean (SD)`[[1]] [1] "60.3" "11.6"

[[3]] [[3]]$Female [[3]]$Female[[1]] [1] "152" "40%"

[[3]]$`Age in Years` [[3]]$`Age in Years`[[1]] NULL

[[3]]$`Mean (SD)` [[3]]$`Mean (SD)`[[1]] [1] "59.8" "11.5"

[[4]] [[4]]$Female [[4]]$Female[[1]] [1] "583"   "38.9%"

[[4]]$`Age in Years` [[4]]$`Age in Years`[[1]] NULL

[[4]]$`Mean (SD)` [[4]]$`Mean (SD)`[[1]] [1] "60"   "11.5"

[[5]] [[5]]$Female [[5]]$Female[[1]] [1] "0.190"

[[5]]$`Age in Years` [[5]]$`Age in Years`[[1]] [1] "0.614"

IOW, je veux une trame de données où la colonne 1 est appelée names [1] et se compose de frameLists [[1]].

Selon les suggestions ci-dessous, j'ai changé mon code comme suit:

outFrame <- do.call(data.frame, c(frameLists, stringsAsFactors = FALSE))
colnames(outFrame) <- cols

Les résultats reviennent comme ceci:

  A: Ike (N=428) F: Mike (N=691) G: Bike (N=380) Total (N=1499) p value   NA     NA   NA    NA    NA 
1            151            59.7             280           60.3     152 59.8    583   60 0.190 0.614 
2          35.3%            11.4           40.5%           11.6     40%  1.5  38.9% 11.5 0.190 0.614

Les résultats que je veux:

  A: Ike (N=428) F: Mike (N=691) G: Bike (N=380) Total (N=1499) p value
1     151, 35.3%      280, 40.5%        152, 40%     583, 38.9%   0.190
2                                                                 0.614
3     59.7, 11.4      60.3, 11.6      59.8, 11.5       60, 11.5        
-3
Greg Dougherty 30 déc. 2015 à 05:04

3 réponses

Meilleure réponse

Construit ce qui suit pour répondre à mes besoins. C'est maladroit, mais jusqu'à présent, cela fonctionne. Premièrement: la sortie:

> myDF
             A: Ike (N=428)   F: Mike (N=691) G: Bike (N=380) Total (N=1499) p value
Female           151, 35.3%        280, 40.5%        152, 40%     583, 38.9%   0.190
Age in Years                                                                   0.614
Mean (SD)        59.7, 11.4        60.3, 11.6      59.8, 11.5       60, 11.5        
Q1, Q3               53, 68            52, 69          52, 68         52, 68        
Range                27, 88            19, 88          26, 85         19, 88        

Maintenant, le code qui l'a généré:

#' Make a data.frame given the column headers and data to fill the data.frame
#' 
#' @param cols          Vector of text holding the column names
#' @param frameLists    List of lists holding the data for the data frame.  First list element 
#' must have all the names used in frameLists. Must be as many lists in frameLists as there are 
#' Strings in cols
#' @returnType  Data Frame
#' @return  Data Frame with all the elements set up and filled in
buildFrame <- function (cols, frameLists) {
    outList <- list()
    for (col in cols) {
        outList[[col]] <- NA
    }

    outFrame = data.frame(outList, stringsAsFactors = FALSE)
    colnames(outFrame) <- cols

    outList <- list()
    for (col in cols) {
        outList[[col]] <- list()
    }

    theNames <- names(frameLists[[1]])
    whichCol <- 1
    for (topList in frameLists) {
        colList <- outList[[whichCol]]
        for (aName in theNames) {
            data <- topList[[aName]]
            if (is.null(data)) {
                colList[[aName]] <- ""
            }
            else {
                colList[[aName]] <- data
            }
        }
        outList[[whichCol]] <- colList
        whichCol <- whichCol + 1
    }

    outFrame <- rbind(outList, outFrame)
    outFrame <- outFrame[-1 - length(theNames), ]
    rownames(outFrame) <- theNames

    return(outFrame)
}
0
Greg Dougherty 5 janv. 2016 à 17:18

En supposant que toutes les listes contiennent le même nombre de chaînes, essayez

result <- do.call(data.frame, c(lapply(frameLists, unlist), stringsAsFactors=F))
names(result) <- name

Exemple de données de liste de listes (je ne sais pas si c'est ce que vous vouliez dire, veuillez fournir des exemples de données autrement) et vecteur de nom

frameLists <- list(list(c("asd", "faf"), NULL, c("3", "2")), list(c("aaa", "zzz"),NULL, c("1", "3")), list(c("qw", "gs"), NULL, c("3", "2")))
name <- c("a", "b", "c")

Production

> result
    a   b  c
1 asd aaa qw
2 faf zzz gs
3   3   1  3
4   2   3  2
> str(result)
'data.frame':   4 obs. of  3 variables:
 $ a: chr  "asd" "faf" "3" "2"
 $ b: chr  "aaa" "zzz" "1" "3"
 $ c: chr  "qw" "gs" "3" "2"

Une autre interprétation possible (je ne sais pas quelle sortie vous voulez) de la même entrée:

res <- as.data.frame(do.call(cbind, lapply(frameLists, function(x) do.call(cbind, x))), stringsAsFactors=F)

La sortie est

> res
   V1 V2  V3 V4 V5 V6
1 asd  3 aaa  1 qw  3
2 faf  2 zzz  3 gs  2
> str(res)
'data.frame':   2 obs. of  6 variables:
 $ V1: chr  "asd" "faf"
 $ V2: chr  "3" "2"
 $ V3: chr  "aaa" "zzz"
 $ V4: chr  "1" "3"
 $ V5: chr  "qw" "gs"
 $ V6: chr  "3" "2"
2
Ricky 31 déc. 2015 à 01:36

Votre code ne fonctionne pas, car vous avez initialisé results en tant que bloc de données vide, ce que R considère comme un bloc de données avec 0 ligne et 0 colonne. Lors de l'ajout d'une colonne à un bloc de données, son nombre de lignes doit correspondre à celui du bloc existant. C'est pourquoi vous avez reçu le message d'erreur replacement has 2 rows, data has 0.

Il serait plus facile de lier une liste de colonnes ensemble dans un dataframe en même temps. Le problème est que la fonction data.frame ne veut pas de liste, elle veut que chaque colonne soit un argument séparé:

data.frame(c(1,2,3),c(4,5,6),c(34,1,1)).

Comment faire pour data.frame prendre une liste de colonnes plutôt que plusieurs arguments?

C'est à ça que sert do.call!

Donnez à do.call une fonction et une liste d'arguments, et il traite les arguments à la fonction un par un.

colList <- list(c(1,2,3),c(4,5,6),c(34,1,1))
col_names <- c('a','b','c')
df <- do.call(data.frame,colList)
colnames(df) <- col_names

Résultat:

> df
  a b  c
1 1 4 34
2 2 5  1
3 3 6  1

Fonctionne aussi bien si colList est une liste de vecteurs de chaînes, mais vous pouvez utiliser stringsAsFactors = F pour éviter la conversion de facteur par data.frame.

2
Paul 30 déc. 2015 à 11:34