J'ai une liste d'employés et j'ai besoin de savoir dans quel département ils travaillent le plus souvent. Il est simple de classer l'ID d'employé par rapport au nom du service, mais il est plus difficile de renvoyer le nom du service, plutôt que le nombre de comptes de liste, à partir de la table de fréquence. Un exemple simple ci-dessous (noms de colonnes = départements, noms de lignes = identifiants d'employés).
DF <- matrix(sample(1:9,9),ncol=3,nrow=3)
DF <- as.data.frame.matrix(DF)
> DF
V1 V2 V3
1 2 7 9
2 8 3 6
3 1 5 4
Maintenant comment puis-je obtenir
> DF2
RE
1 V3
2 V1
3 V2
Réponses:
Une option utilisant vos données (pour référence future, utilisez
set.seed()
pour faire des exemples en utilisantsample
reproductible):Une solution plus rapide que l'utilisation
apply
pourrait êtremax.col
:... où
ties.method
peut être l'un des"random"
"first"
ou"last"
Cela pose bien sûr des problèmes si vous avez deux colonnes égales au maximum. Je ne suis pas sûr de ce que vous voulez faire dans ce cas car vous aurez plus d'un résultat pour certaines lignes. Par exemple:
la source
which.max
sera alors très bien.apply
convertit ledata.frame
enmatrix
interne. Cependant, vous ne verrez peut-être pas de différence de performances sur ces dimensions.colnames(DF)[max.col(replace(DF, cbind(seq_len(nrow(DF)), max.col(DF,ties.method="first")), -Inf), "first")]
Si vous êtes intéressé par une
data.table
solution, en voici une. C'est un peu délicat car vous préférez obtenir l'id pour le premier maximum. C'est beaucoup plus facile si vous préférez le dernier maximum. Néanmoins, ce n'est pas si compliqué et c'est rapide!Ici, j'ai généré des données de vos dimensions (26746 * 18).
Les données
data.table
répondre:Analyse comparative:
C'est environ 11 fois plus rapide sur les données de ces dimensions et
data.table
évolue assez bien aussi.Edit: si l'un des identifiants max est correct, alors:
la source
Une solution pourrait être de remodeler la date de large à long en plaçant tous les départements dans une colonne et en comptant dans une autre, en les regroupant par identifiant d'employeur (dans ce cas, le numéro de ligne), puis en filtrant sur le (s) département (s) avec le Valeur max. Il existe également plusieurs options pour gérer les liens avec cette approche.
la source
Sur la base des suggestions ci-dessus, la
data.table
solution suivante a fonctionné très rapidement pour moi:Et vient également avec l'avantage de pouvoir toujours spécifier les colonnes à
.SD
prendre en compte en les mentionnant dans.SDcols
:Au cas où nous aurions besoin du nom de colonne de la plus petite valeur, comme suggéré par @lwshang, il suffit d'utiliser
-.SD
:la source
which.min
dans quelque chose qui ressemblerait à:DT[, MIN := colnames(.SD)[apply(.SD,1,which.min)]]
ouDT[, MIN2 := colnames(.SD)[which.min(.SD)], by = 1:nrow(DT)]
sur les données factices ci-dessus. Cela ne prend pas en compte les liens et ne renvoie que le premier minimum. Pensez peut-être à poser une question distincte. Je serais également curieux de savoir quelles autres réponses vous obtiendriez.colnames(.SD)[max.col(-.SD, ties.method="first")]
.Une
dplyr
solution:Idée:
Code:
Résultat:
Cette approche peut être facilement étendue pour obtenir les
n
colonnes du haut . Exemple pourn=2
:Résultat:
la source
Une simple
for
boucle peut également être pratique:la source
Une option
dplyr 1.0.0
pourrait être:Exemple de données:
la source
Voici une réponse qui fonctionne avec data.table et qui est plus simple. Cela suppose que votre data.table est nommé
yourDF
:Remplacez
("V1", "V2", "V3", "V4")
et(V1, V2, V3, V4)
par vos noms de colonnesla source