2016-10-13 4 views
3

J'ai données d'absence des employés en tant que trame de données dans le format suivant:R - colonnes de remplissage automatique dans une trame de données à partir d'une plage de dates

EmpID Name LeaveFrom LeaveTo 
xz123 ABC 07/12/2016 07/08/2016 
kp546 PQR 06/28/2016 07/02/2016  
xz123 ABC 07/25/2016 07/27/2016 

Un employé peut avoir plus d'une ligne assignée à lui/elle .

Je voudrais créer un DF qui reflète ce qui précède dans le format suivant:

EMPID Name Jul-01 Jul-02 Jul03 ..Jul07 Jul08....Jul25 Jul26 Jul27 .Jul 31 

xz123 ABC P  P  P ... A  A   A  A  A  P 
kp546 PQR A  A  P  P  P   P  P  P  P 

où P signifie Présence et A pour absence.

Une idée de comment cela pourrait être fait. J'ai environ 30000 dossiers

+3

On dirait que vous voulez nous d'écrire un code pour vous. Bien que de nombreux utilisateurs soient prêts à produire du code pour un codeur en détresse, ils ne font généralement que contribuer lorsque l'affiche a déjà tenté de résoudre le problème par eux-mêmes. Une bonne façon de démontrer cet effort est d'inclure le code que vous avez écrit jusqu'à présent, l'exemple d'entrée (s'il y en a), la sortie attendue, et la sortie que vous obtenez réellement (sortie console, retraçages, etc.). Plus vous fournissez de détails, plus vous aurez de chances de recevoir des réponses. Vérifiez la [FAQ] et [demander]. – symbolrush

+1

Il devrait y avoir un script automatisé pour détecter l'absence de code/effort de l'utilisateur dans la résolution du problème et afficher ce qui précède comme premier commentaire! – OdeToMyFiddle

+0

La seule façon que je connaissais était de faire une boucle pour chaque rangée. Ce que je pense n'est pas le plus élégant des moyens. –

Répondre

0

Voici ma tentative:

library(reshape2) 
df <- read.table(text = "EmpID Name LeaveFrom LeaveTo 
    xz123 ABC 07/12/2016 07/18/2016 
    kp546 PQR 06/28/2016 07/02/2016  
    xz123 ABC 07/25/2016 07/27/2016", header = TRUE) 

## Convert is to date format first 
df$LeaveFrom <- as.Date(df$LeaveFrom, "%m/%d/%Y") 
df$LeaveTo <- as.Date(df$LeaveTo, "%m/%d/%Y") 

## get sequence of dates to use 
dates <- seq(min(df$LeaveFrom), max(df$LeaveTo), by = 1) 
present <- rep("P", length(dates)) 

## apply the following function for every EmpID 
resList <- lapply(split(df, df$EmpID), function(x){ 
    ## You need reshape2 packages to do this 
    ## If you don't have it, you can install it: install.packages("reshape2") 

    mL <- melt(x, id.vars = c("EmpID", "Name")) 

    ## Number of rows is equal to the number of breaks 
    ## It should be equal to number of times a given EmpID appears in df 
    ## first column is the date at which the break began and second column is the date at which the break ended 
    ## Instead of using dates, I convert them to indices of "dates" vector defined above 
    m <- matrix(match(mL$value, dates), ncol = 2) 

    ## make a vector of dates (indices) when an employee was absent 
    absent <- unlist(apply(m, 1, function(x){ 
     x[1]:x[2] 
    })) 

    ## mark absent 
    present[absent] <- "A" 
    return(present) 
}) 

df.final <- as.data.frame(do.call("rbind", resList)) 

## change date format to make it easier to read 
colnames(df.final) <- format(dates, "%m/%d") 
print(df.final) 

##  06/28 06/29 06/30 07/01 07/02 07/03 07/04 07/05 07/06 07/07 07/08 07/09 07/10 07/11 07/12 07/13 07/14 07/15 07/16 07/17 07/18 07/19 07/20 07/21 07/22 07/23 07/24 07/25 07/26 07/27 
## kp546  A  A  A  A  A  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  P 
## xz123  P  P  P  P  P  P  P  P  P  P  P  P  P  P  A  A  A  A  A  A  A  P  P  P  P  P  P  A  A  A