2017-10-03 13 views
1
demodf <- data.frame(
    name = c("Mike","Mike","Mike","Mike","Mike","Joe","Joe","Joe","Joe","Joe"), 
    Field = c("EDUCATION","Degree","Title","WORK", "Title", "EDUCATION","Degree","Title", "WORK","Title"), 
    Values = c("EDUCATION", "Masters", "Student", "WORK", "VP Sales", "EDUCATION", "Bachelors","Student", "WORK", "Analyst")) 

    name  Field Values 
1 Mike EDUCATION EDUCATION 
2 Mike Degree Masters 
3 Mike  Title Student 
4 Mike  WORK  WORK 
5 Mike  Title VP Sales 
6 Joe EDUCATION EDUCATION 
7 Joe Degree Bachelors 
8 Joe  Title Student 
9 Joe  WORK  WORK 
10 Joe  Title Analyst 

Je veux tidyr::spread ou reshape2::dcast en grand format, où Field devient les en-têtes de colonnes. Ce code ressemblerait à dcast(demodf, name ~ Values) ou demodf %>% spread(Field, Values). Cependant, dcast génère une valeur numérique et spread génère une erreur.données Tidy et coulé avec en-têtes Coincé dans les lignes

Le problème est que "Titre" se répète. Vous pouvez voir qu'en raison d'une bizarrerie dans les données, nous avons EDUCATION et WORK comme "faux" en-têtes dans les données. Est-il possible d'étiqueter chaque entrée Field avec l'en-tête en majuscule afin que dcast fonctionne (c'est-à-dire Title_EDUCATION et Title_WORK)? Et il serait encore mieux d'appliquer cette transformation à l'ensemble Field, donc "EDUCATION" et "WORK" disparaissent tous ensemble, et il nous reste Degree_EDUCATION, TITLE_EDUCATION ... etc).

Notez qu'il ya beaucoup plus d'en-têtes dans les données réelles, il serait donc préférable d'identifier les « faux têtes » comme les entrées toutes capitalisations, ou les entrées où Field == Values

sortie souhaitée:

output <- data.frame(
Name=c("Mike", "Joe"), 
Degree_EDUCATION =c("Masters", "Bachelors"), 
Title_EDUCATION = c("Student", "Student"), 
Title_WORK= c("VP Sales", "Analyst")) 

    Name Degree_EDUCATION Title_EDUCATION Title_WORK 
1 Mike   Masters   Student VP Sales 
2 Joe  Bachelors   Student Analyst 

Répondre

3

La clé est d'ajouter cette ligne de catégorie répétée comme une nouvelle colonne, alors vous pouvez travailler avec facilement.

Tout d'abord, l'ajout stringsAsFactors=FALSE peut donc comparer Field et Values:

demodf <- data.frame(
    name = c("Mike","Mike","Mike","Mike","Mike","Joe","Joe","Joe","Joe","Joe"), 
    Field = c("EDUCATION","Degree","Title","WORK", "Title", "EDUCATION","Degree","Title", "WORK","Title"), 
    Values = c("EDUCATION", "Masters", "Student", "WORK", "VP Sales", "EDUCATION", "Bachelors","Student", "WORK", "Analyst"), 
    stringsAsFactors=FALSE) 

Maintenant, utilisez tidyr et dplyr pour ajouter des colonnes pour si cette ligne est une catégorie et le nom de cette catégorie, pour remplir le bas disparus valeurs, puis pour supprimer les lignes et les colonnes supplémentaires.

library(tidyr) 
library(dplyr) 
d2 <- demodf %>% mutate(IsCategory=Field==Values, 
         Category=ifelse(IsCategory, Field, NA)) %>% 
    fill(Category) %>% subset(!IsCategory, select=-IsCategory) 
d2 
## name Field Values Category 
## 2 Mike Degree Masters EDUCATION 
## 3 Mike Title Student EDUCATION 
## 5 Mike Title VP Sales  WORK 
## 7 Joe Degree Bachelors EDUCATION 
## 8 Joe Title Student EDUCATION 
## 10 Joe Title Analyst  WORK 

dcast fonctionne alors comme vous l'espérez!

library(reshape2)  
dcast(d2, name ~ Field+Category, value.var="Values") 
## name Degree_EDUCATION Title_EDUCATION Title_WORK 
## 1 Joe  Bachelors   Student Analyst 
## 2 Mike   Masters   Student VP Sales 
+0

fantastique, merci. Le bit 'mutate' pour assigner le tag' IsCategory' est un truc génial. – Mako212

0

Voici une tentative avec data.table. Cela nécessite que stringsAsFactors = FALSE soit utilisé.

library(data.table) 
# get groupings by titles (all caps) 
setDT(demodf)[, head := cumsum(Field == toupper(Field))] 
# merge titles onto full dataset and paste title to Field 
demodf[demodf[Field == toupper(Field), .(Field, head)], on="head", 
     Field := paste(Field, i.Field, sep="_"), by=.EACHI] 
# now reshape wide 
dcast(demodf[Values != toupper(Values),], name~Field, value.var="Values") 

Ce retour

name Degree_EDUCATION Title_EDUCATION Title_WORK 
1: Joe  Bachelors   Student Analyst 
2: Mike   Masters   Student VP Sales 

données

demodf <- 
structure(list(name = c("Mike", "Mike", "Mike", "Mike", "Mike", 
"Joe", "Joe", "Joe", "Joe", "Joe"), Field = c("EDUCATION", "Degree", 
"Title", "WORK", "Title", "EDUCATION", "Degree", "Title", "WORK", 
"Title"), Values = c("EDUCATION", "Masters", "Student", "WORK", 
"VP Sales", "EDUCATION", "Bachelors", "Student", "WORK", "Analyst" 
)), .Names = c("name", "Field", "Values"), row.names = c(NA, 
-10L), class = "data.frame")