2016-11-14 2 views
1

J'ai deux variables avec plusieurs niveaux; V1 a 400 niveaux et V2 a ≈ 250 niveaux. Comment puis-je transformer les facteurs de V2 en plusieurs variables différentes et utiliser la variable V1 comme identifiant unique?R Conversion de facteurs en nouvelles variables

V1    V2 
Garza, Mike a 
Garza, Mike b 
Smith, James a 
Smith, James f 
Smith, James z 
Moore, Jen  b 
Klein, April f 

L'image ressemblera à l'exemple ci-dessous. Note: Comment les variables peuvent contenir plusieurs facteurs, pas une variable par facteur. Considérant que Mike a deux facteurs associés à lui, les facteurs a et b vont dans V2 et V3, où Jen, le facteur b va également dans V2, pas V3.

V1    V2 V3 V4 V5 
Garza, Mike a b 
Smith, James a f z 
Moore, Jen  b 
Klein, April f 

Toute aide serait grandement appréciée!

Merci.

Répondre

1

Vous pouvez effectuer la première partie avec dcast dans le package reshape, puis les trier à la sortie souhaitée avec apply.

dat <- data.frame(V1 = factor(c("Garza", "Garza", 
          "Smith", "Smith", "Smith", 
          "Moore", "Klein")), 
        V2 = c("a","b","a","f","z","b","f")) 

# recast your data 
dd <- dcast(dat, V1~V2) 

#make a function to use with apply 

shift_values<- function(x){ 
    notna <-which(!is.na(x[-1])) 
    val <- x[notna+1] 
    x[-1] <- c(as.character(val), rep("", (length(x)-1-length(val)))) 
    return(x) 
} 

# use it in an apply loop, transpose the data, and turn it into a data.frame 
result <- data.frame(t(apply(dd, 1, shift_values))) 

# change the column names 
colnames(result)[-1] <- paste0("V", 2:(ncol(result))) 

Les données se présente alors comme ceci:

 V1 V2 V3 V4 V5 
1 Garza a b  
2 Klein f   
3 Moore b   
4 Smith a f z 
3

Ceci est un problème de remodelage. Considérez df est votre data.frame, vous pouvez essayer d'utiliser ceci:

> library(reshape2) 
> print(dcast(melt(df), ...~V2), na.print="") 
Using V1, V2 as id variables 
Using V2 as value column: use value.var to override. 
      V1 a b f z 
1 Garza,Mike a b  
2 Klein,April  f 
3 Moore,Jen b  
4 Smith,James a f z 
+0

Salut Jilber, merci pour la réponse! Pouvez-vous s'il vous plaît jeter un oeil une fois de plus à la poste? J'ai fait un léger montage, pour que ma question soit plus claire. Je vous remercie. – Starbucks

1

Il semble que vous voulez un vecteur des V2 niveaux qui sont présents pour chaque niveau V1 (individuel). Ce n'est pas vraiment comment les colonnes sont conçues pour fonctionner dans data.frames, même si vous pouvez le faire dans Excel. Au lieu de cela, je suggère que vous venez de faire le résultat un vecteur pour chaque individu, comme suit:

split(df$V2, df$V1) 

qui retourne:

$`Garza, Mike` 
[1] a b 
Levels: a b f z 

$`Klein, April` 
[1] f 
Levels: a b f z 

$`Moore, Jen` 
[1] b 
Levels: a b f z 

$`Smith, James` 
[1] a f z 
Levels: a b f z 

Sans connaître votre cas d'utilisation, je ne peux pas dire si cela sera en fait meilleur ou pas. Cependant, dans mon expérience générale, il est plus facile de travailler avec. Si vous avez juste besoin de les imprimer, vous pouvez toujours les réduire. Par exemple, si vous enregistrez le résultat split ci-dessus pour out, vous pouvez faire cela, qui peut ensuite être ajouté comme une colonne à une autre table de sortie:

out <- split(df$V2, df$V1) 

sapply(out, paste, collapse = ", ") 

donne

Garza, Mike Klein, April Moore, Jen Smith, James 
     "a, b"   "f"   "b" "a, f, z" 

Ou, si vous voulez savoir qui a un certain groupe, vous pouvez le faire:

sapply(out, function(x){"f" %in% x}) 

ce qui donne:

Garza, Mike Klein, April Moore, Jen Smith, James 
     FALSE   TRUE  FALSE   TRUE