J'ai un ensemble de données qui ressemble à ce ici, J'ai changé mes exemples et inclus le poste de travail, car cela reflète plus ce que je veux faire avec le jeu de données d'origine. Les réponses de ce fil ne fonctionne que lorsqu'il n'y a que des gestionnaires et des patrons dans l'ensemble de données - de sorte que toute suggestion pour la fabrication de ce travail serait formidable. Je serai très reconnaissant !! p> p> job2 code> désigne une variable factice indiquant si une personne était un
manager code > Au cours de cette année ou non. Je veux faire deux choses à ce jeu de données: premièrement, je veux seulement conserver la ligne lorsque la personne est devenue
patron code> pour la première fois. Deuxièmement, j'aimerais voir des années cumulatives qu'une personne a fonctionné comme un code> manager stocke et stocke ces informations dans la variable
cumu_job2 code>. Ainsi, je voudrais avoir: p>
5 Réponses :
contribué par Matthew Dowle: explication p> Les versions plus anciennes: p> Vous avez deux fractions différentes applicables à des combines ici. Un pour obtenir les emplois cumulatifs et l'autre pour obtenir la première rangée du statut de patron. Voici une implémentation dans Remarque Ce tableau suppose est trié par année dans chaque Vous pouvez également accéder à la même chose avec: p> L'idée est d'obtenir essentiellement les numéros de ligne où la condition correspond à la condition (avec < code> .Je code> - variable interne), puis sous-ensemble
.sd code>) li>
data.Table. / code> où nous effectuons essentiellement chaque analyse séparément (bien, type de), puis collectez tout au même endroit avec
RBind code>. La principale chose à noter est la pièce
by = id code>, qui signifie essentiellement que les autres expressions sont évaluées pour chaque groupe code> ID code> dans les données, ce qui était ce que vous avez correctement noté manquait. De votre tentative. p>
ID code>, mais si ce n'est pas suffisamment facile à réparer. p>
dt code> sur ces numéros de ligne (le
$ V1 code> partie), puis effectuez simplement la somme cumulative. p> p>
Merci beaucoup! J'ai une erreur si - Type de RHS ('Integer') doit correspondre à LHS ('Double'). Pour vérifier et contraindre aurait trop d'impact sur la performance pour les cas les plus rapides. Changez le type de la colonne cible ou coerce le RHS de: = vous-même (par exemple en utilisant 1L au lieu de 1)
Je ne comprends pas vraiment cela parce que j'ai tourné les vecteurs ID et Job2 en vecteurs entier à travers AS.Integer Command ....
J'ai lu Stackoverflow.com/Questtions/16361225/... et résolu le problème - tout simplement cumujob: = AS.numérique (Cumsum (Job2))) à la place.
En ce qui concerne la lisibilité, j'irais avec: dt [ .sd [travail! = "Patron" | Année == min (année)] [ cumjob: = cumsum (job2)], by = liste (nom, travail)] code>
@eddi hi - j'ai une autre question! Donc, si j'ai d'autres postes que les gestionnaires, comment puissierais-je conserver toutes les informations? Je n'ai pas bien précisé cette partie dans ma question, mais je pense que DT [Job2 == 1] Cela fait que cela vous achemine beaucoup d'informations dans mon ensemble de données.
Pour le dernier code, je reçois une erreur dans [. Data.frame code> (exentacc , .sd [ccmem == 0 | année == min (année)] [: argument non utilisé (par = liste (nom, Prov.1))
Le deuxième code provoque une même erreur d'erreur aussi - argument inutilisé (by = liste (nom1, CCMEM))
@ Rusuer9000, assurez-vous d'ajouter la Ligne Bibliothèque (Data.Table) CODE> Avant d'exécuter cette ligne. Le dernier fonctionne bien pour moi. Je n'ai pas testé le second. Si le package n'est pas installé, vous devrez alors exécuter
installer.backages ("data.table") code> premier.
@ Rusuer9000 Vous avez déjà cette information dans les données, au lieu de penser à la manière de représenter cette information comme un numéro, que diriez-vous de sauter cette partie et d'aller directement à la prochaine étape de ce que vous voulez faire.
@ Brodieg est bien meilleur:
les données forte> p> inds1 <- rle(dat$job2)
inds2 <- cumsum(inds1[[1]])[inds1[[2]] == 1] + 1
ends <- cumsum(inds1[[1]])
starts <- c(1, head(ends + 1, -1))
inds3 <- mapply(":", starts, ends)
dat$id <- rep(1:length(inds3), sapply(inds3, length))
dat <- do.call(rbind, lapply(split(dat[, 1:5], dat$id ), function(x) {
if(x$job2[1] == 0){
x$cumu_job2 <- rep(0, nrow(x))
} else {
x$cumu_job2 <- 1:nrow(x)
}
x
}))
keeps <- dat$job2 > 0
keeps[inds2] <- TRUE
dat2 <- data.frame(dat[keeps, ], row.names = NULL)
dat2
## id name year job job2 cumu_job2
## 1 1 Jane 1980 Manager 1 1
## 2 1 Jane 1981 Manager 1 2
## 3 1 Jane 1982 Manager 1 3
## 4 1 Jane 1983 Manager 1 4
## 5 1 Jane 1984 Manager 1 5
## 6 1 Jane 1985 Manager 1 6
## 7 2 Jane 1986 Boss 0 0
## 8 3 Bob 1985 Manager 1 1
## 9 3 Bob 1986 Manager 1 2
## 10 3 Bob 1987 Manager 1 3
## 11 4 Bob 1988 Boss 0 0
Devinez que vous avez une chose contre succinct?
@psguy Je suppose que vous avez une chose contre les manières? Votre réponse était très succincte cependant.
voici la solution Remarque: assurez-vous que sortie: p> explication p> dplyr code> dplyr code> pour le même problème.
stringsasfactors = false code> en lisant dans les données. P> < Pré> xxx pré>
cumu_job2 code> colonne. LI>
ol> p>
La même idée sur le filtrage peut être utilisée avec data.table code>:
dt [ liste (cum_job2 = cumsum (job2 [travail! = "Boss" | Année == min (année)]) ), par = c ("nom", "travail")] code>
@Ramnath J'aimerais savoir pourquoi cela ne fonctionne pas pour moi - je ne peux pas installer dplyr et%.% N'est pas une fonction.
%.% code> est une fonction dans
dplyr code>.
dplyr code> est sur Cran, il devrait donc être simple d'installer à l'aide de
install_packages code>.
@Ramnath Avertissement dans Install.Packages: Le package 'dplyr' n'est pas disponible (pour la version 3.0.0) quelle version r travaillez-vous?
@Ramnath J'ai aussi essayé devtools :: install_github ("hadley / dplyr") mais il dit que l'erreur client: 404 non trouvé
Donc, j'ai mis à jour r mais cela n'a pas fonctionné - il vient de créer un cumul de Job2 jusqu'à la fin (quelle que soit chaque observation)
Je ne comprends pas quelle sortie vous avez eue. Une chose à prendre soin est de vous assurer que plyr code> n'est pas chargé en même temps que
dplyr code>, car cela pourrait entraîner des conflits. J'ai mis à jour ma réponse avec la sortie, ce que je crois, c'est ce que vous recherchiez.
Je pense que cela fait ce que vous voulez, bien que les données soient triées comme vous l'avez présentée.
my.df <- read.table(text = ' id name year job job2 1 Jane 1980 Worker 0 1 Jane 1981 Manager 1 1 Jane 1982 Manager 1 1 Jane 1983 Manager 1 1 Jane 1984 Manager 1 1 Jane 1985 Manager 1 1 Jane 1986 Boss 0 1 Jane 1987 Boss 0 2 Bob 1985 Worker 0 2 Bob 1986 Worker 0 2 Bob 1987 Manager 1 2 Bob 1988 Boss 0 2 Bob 1989 Boss 0 2 Bob 1990 Boss 0 2 Bob 1991 Boss 0 2 Bob 1992 Boss 0 ', header = TRUE, stringsAsFactors = FALSE) my.seq <- data.frame(rle(my.df$job)$lengths) my.df$cumu_job2 <- as.vector(unlist(apply(my.seq, 1, function(x) seq(1,x)))) my.df2 <- my.df[!(my.df$job=='Boss' & my.df$cumu_job2 != 1),] my.df2$cumu_job2[my.df2$job != 'Manager'] <- 0 id name year job job2 cumu_job2 1 1 Jane 1980 Worker 0 0 2 1 Jane 1981 Manager 1 1 3 1 Jane 1982 Manager 1 2 4 1 Jane 1983 Manager 1 3 5 1 Jane 1984 Manager 1 4 6 1 Jane 1985 Manager 1 5 7 1 Jane 1986 Boss 0 0 9 2 Bob 1985 Worker 0 0 10 2 Bob 1986 Worker 0 0 11 2 Bob 1987 Manager 1 1 12 2 Bob 1988 Boss 0 0
Voici une solution de base utilisant révision: utilise maintenant dans code> et
AVE code>. Nous supposons que l'entrée est
df code> et que les données sont triées comme dans la question.
dans code>. < / p> p>