2010-11-04 10 views
1

J'ai une trame de données avec une variable de réponse, Y, et trois facteurs, « facteur.Procédé », « factor.b » et « factor.c »puis-je éviter ces boucles for imbriquées?

Je suis en train d'écrire une fonction qui

  1. supprimer une colonne d'une trame de données si tous les niveaux du facteur sont les mêmes

  2. ajouter les termes beta.factor.x [1..n] 'un vecteur de paramètres quand il est plus d'un niveau d'un facteur, jusqu'à 5 niveaux.

  3. ne comprennent pas le paramètre beta.factor.b [1] de la liste (il est fixe)

Voici mon code. Je pense que ça a l'air bien et fonctionne bien, mais j'ai lu qu'il est préférable d'éviter les boucles imbriquées, donc je suis curieux de savoir s'il existe une approche plus efficace.

data <- data.frame(  y = c(1,2,3,4), 
        factor.a = c(1, 1, 2, 1), 
        factor.b = c(1, 2, 2, 3), 
        factor.c = c(0, 0, 0, 0)) 

model.parms <- list(factor.a = length(unique(data$factor.a)), 
        factor.b = length(unique(data$factor.b)), 
        factor.c = length(unique(data$factor.c))) 
vars <- 'beta.o' 
for (x in c('factor.a','factor.c', 'factor.b')) { 
    if(model.parms[[x]] == 1) { 
    data <- data[, -which(names(data) == x)] 
    } else { 
    m <- min(model.parms[[x]], 5) 
    for (i in 1:m) { 
     if(!i == 1 && x == 'factor.b') { 
     vars <- c(vars, paste('beta.', x, '[', i, ']', sep='')) 
     } 
    } 
    } 
} 

Répondre

2

Vous ne avez pas besoin de boucles du tout

vars <- c('beta.o', 
    paste('sd.', names(model.parms)[model.parms > 1], sep = ''), 
    paste('beta.factor.b', '[', 1 + seq_len(min(model.parms[["factor.b"]], 5) - 1), ']', sep='') 
) 
data <- data[, names(model.parms)[model.parms > 1]] 
+0

Cela semble très agréable, et me pointe certainement dans la bonne direction pour simplifier mon code, mais je remarque deux choses: d'abord, «x» n'est pas défini dans votre réponse (il était dans ma boucle for, et deuxièmement, le –

+1

J'ai changé le code, il devrait maintenant donner le même résultat que votre code, bien que je remarque que vous ayez omis la partie avec sd dans votre code original – Thierry

+0

Merci. supprimé sd juste pour simplifier la question votre approche fonctionne bien –

1

Vous pouvez boucles imbriquées souvent vides avec par(). Prenant votre trame de données,

> out <- by(data,data[,-1],identity) 
> out 

vous obtiendrez

factor.a: 1 
factor.b: 1 
factor.c: 0 
    y factor.a factor.b factor.c 
1 1  1  1  0 
------------------------------------------------------------ 
factor.a: 2 
factor.b: 1 
factor.c: 0 
NULL 
------------------------------------------------------------ 
factor.a: 1 
factor.b: 2 
factor.c: 0 
    y factor.a factor.b factor.c 
2 2  1  2  0 
------------------------------------------------------------ 
factor.a: 2 
factor.b: 2 
factor.c: 0 
    y factor.a factor.b factor.c 
3 3  2  2  0 
------------------------------------------------------------ 
factor.a: 1 
factor.b: 3 
factor.c: 0 
    y factor.a factor.b factor.c 
4 4  1  3  0 
------------------------------------------------------------ 
factor.a: 2 
factor.b: 3 
factor.c: 0 
NULL 

si vous unclass(out), vous obtiendrez une matrice ou un tableau du mode list; chaque élément contiendra les lignes de la trame de données d'origine qui est agrégée par les niveaux spécifiés dans le deuxième argument de by(). Bien sûr, vous pouvez remplacer la fonction identity par une autre fonction qui fonctionne sur ce sous-ensemble de la trame de données (la sortie sera toujours une matrice ou un tableau, mais pas nécessairement du mode list, selon ce que vous retournez de votre fonction).

Questions connexes