web-dev-qa-db-fra.com

Ajouter des colonnes à un cadre de données vide dans R

J'ai longuement cherché, mais je n'ai pas trouvé de réponse à cette question sur Stack Overflow.

Disons que j'ai un cadre de données a.

Je définis:

a <- NULL
a <- as.data.frame(a)

Si je voulais ajouter une colonne à ce cadre de données de la manière suivante:

a$col1 <- c(1,2,3)

Je reçois l'erreur suivante:

Error in `$<-.data.frame`(`*tmp*`, "a", value = c(1, 2, 3)) : 
    replacement has 3 rows, data has 0

Pourquoi la dimension de la ligne est-elle fixe alors que la colonne ne l'est pas?

Comment changer le nombre de lignes dans un cadre de données?

Si je le fais (en saisissant d'abord les données dans une liste, puis en les convertissant en df), cela fonctionne correctement:

a <- NULL
a$col1 <- c(1,2,3)
a <- as.data.frame(a)
11
Michal

La dimension de la ligne n'est pas fixe, mais data.frames sont stockés sous forme de liste de vecteurs contraints d'avoir la même longueur. Vous ne pouvez pas ajouter col1 à a car col1 a trois valeurs (lignes) et a a zéro, rompant ainsi la contrainte. Par défaut, R n'analyse pas automatiquement les valeurs lorsque vous tentez d'étendre la dimension d'un data.frame en ajoutant une colonne plus longue que le data.frame. La raison pour laquelle le deuxième exemple fonctionne est que col1 est le seul vecteur du nom data.frame. Le nom data.frame est donc initialisé avec trois lignes. 

Si vous souhaitez que le fichier data.frame soit développé automatiquement, vous pouvez utiliser la fonction suivante:

cbind.all <- function (...) 
{
    nm <- list(...)
    nm <- lapply(nm, as.matrix)
    n <- max(sapply(nm, nrow))
    do.call(cbind, lapply(nm, function(x) rbind(x, matrix(, n - 
        nrow(x), ncol(x)))))
}

Ceci remplira les valeurs manquantes avec NA. Et vous l'utiliseriez comme: cbind.all( df, a )

9
ctbrown

Vous pouvez également faire quelque chose comme ceci: lire des données dans plusieurs fichiers, saisir la colonne que je veux et la stocker dans le cadre de données. Je vérifie si le cadre de données contient quoi que ce soit, et si ce n’est pas le cas, créez-en un nouveau plutôt que d’obtenir l’erreur concernant le nombre incohérent de lignes:

readCounts = data.frame()

for(f in names(files)){
    d = read.table(files[f], header=T, as.is=T)
    d2 = round(data.frame(d$NumReads))
    colnames(d2) = f
    if(ncol(readCounts) == 0){
        readCounts = d2
        rownames(readCounts) = d$Name
    } else{
        readCounts = cbind(readCounts, d2)
    }
}
1
user2820516