Le calcul des pourcentages dans une déclaration applicable (R)
Question
Je suis aux prises avec quelque chose d'assez simple, mais je vais tourner en rond, et ne vois pas où je fais une erreur. J'espère vraiment que quelqu'un pourrait me prêter une suggestion pratique, de sorte que je ne suis plus coincé!
Mon but: Je veux calculer le pourcentage de cas dans un data.frame qui ont un résultat supérieur à 0. Je l'ai essayé avec la boucle, mais en vain. Ainsi, après un peu plus de recherche je l'applique fonction pour calculer différents paramètres comme moyenne, sd, et min / max. Cela fonctionne très bien, mais pour le calcul du pourcentage de la fonction application ne fonctionne pas, même quand je fais une fonction personnalisée et insérer cela dans la fonction appliquer.
Ceci est la version abrégée de mon data.frame:
tradesList[c(1:5,10:15),c(1,7)]
Instrument TradeResult.Currency.
1 JPM -3
2 JPM 264
3 JPM 284
4 JPM 69
5 JPM 283
10 JPM -294
11 KFT -8
12 KFT -48
13 KFT 125
14 KFT -150
15 KFT -206
Je veux résumer ce data.frame, par exemple en affichant la TradeResult moyenne pour chaque instrument:
> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, mean)
JPM KFT
42.3 14.6
Cependant, je voudrais aussi de calculer le pourcentage de lignes qui ont un TradeResult> 0 par instrument. Avec le « qui » contrôle fonction des instances qui sont> 0 ne fonctionne, cependant, demander n'accepte pas cette fonction comme argument.
> length(which(tradesList$TradeResult.Currency. > 0)) / length(tradesList$TradeResult.Currency.) * 100
[1] 50
> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, (length(which(tradesList$TradeResult.Currency. > 0)) / length(tradesList$TradeResult.Currency.) * 100))
Error in match.fun(FUN) :
c("'(length(which(tradesList$TradeResult.Currency. > 0))/length(tradesList$TradeResult.Currency.) * ' is not a function, character or symbol", "' 100)' is not a function, character or symbol")
>
Je recherche dans la fonction d'aide pour plus d'informations sur cette erreur, et a essayé différentes manières de formuler la fonction (par exemple avec des crochets ou des guillemets), mais chaque chemin a conduit au même résultat.
Est-ce que quelqu'un sait un whay pour calculer le pourcentage de cas qui sont supérieurs à zéro? Peut-être que je manque quelque chose?
Merci beaucoup à l'avance,
Cordialement,
Edit: Merci beaucoup pour vos commentaires rapides G. Grothendieck, Gavin Simpson et dwin. Très apprécié et très utile!
Résolu: Voici ce que j'ai maintenant:
> tmpData <- tradesList[c(1:5,10:15),c(1,7)]
> tmpData
Instrument TradeResult.Currency.
1 JPM -3
2 JPM 264
3 JPM 284
4 JPM 69
5 JPM 283
10 JPM -294
11 KFT -8
12 KFT -48
13 KFT 125
14 KFT -150
15 KFT -206
> 100* # to get percentages
+ with( tmpData,
+ tapply( (TradeResult.Currency. > 0) , Instrument, sum)/ # number GT 0
+ tapply( TradeResult.Currency., Instrument, length) ) # total number
JPM KFT
66.66667 20.00000
> 100 * tapply(tmpData$TradeResult.Currency. > 0, tmpData$Instrument, mean)
JPM KFT
66.66667 20.00000
> pcentFun <- function(x) {
+ res <- x > 0
+ 100 * (sum(res) / length(res))
+ }
>
> with(tmpData, tapply(TradeResult.Currency., Instrument, pcentFun))
JPM KFT
66.66667 20.00000
Merci encore!
Cordialement,
La solution
Ecrire une fonction simple calcul:
pcentFun <- function(x) {
res <- x > 0
100 * (sum(res) / length(res))
}
Ensuite, nous pouvons l'appliquer à des groupes d'instruments, via tapply()
> with(tradeList, tapply(TradeResult.Currency, Instrument, pcentFun))
JPM KFT
66.66667 20.00000
mais aggregate()
serait plus utile si vous voulez le résumé avec des noms d'instruments:
> with(tradesList, aggregate(TradeResult.Currency,
+ by = list(Instrument = Instrument), pcentFun))
Instrument x
1 JPM 66.66667
2 KFT 20.00000
Autres conseils
Essayez ceci:
100 * tapply(tradesList$TradeResult.Currency. > 0, tradesList$Instrument, mean)
Avec les données d'échantillon dans le poste lui donne:
JPM KFT
66.67 20.00
et ici, il utilise sqldf (notez que le pilote RSQLite se traduit par des points à underscores puisque les points sont également un opérateur SQL que nous utilisons underscores où les points ont été):
> library(sqldf)
> sqldf("select Instrument,
+ 100 * avg(TradeResult_Currency_ > 0) as '%>0',
+ avg(TradeResult_Currency_) as 'Avg Currency'
+ from tradesList group by Instrument")
Instrument %>0 Avg Currency
1 JPM 66.67 100.5
2 KFT 20.00 -57.4
Ces deux pourraient aussi se traduire par une modification à aggregate
appropriée de la solution aggregate
déjà affichée.
Vous pouvez travailler avec des résultats logiques en utilisant la somme ou la moyenne pour obtenir un résumé des résultats significatifs:
100* # to get percentages
with( tradesList,
tapply( (TradeResult.Currency. > 0) , Instrument, sum)/ # number GT 0
tapply( TradeResult.Currency., Instrument, length) ) # total number
Edit: Je remarque que Gavin vous a donné une réponse qui a rendu un dataframe, une classe généralement bien comprise. La classe des valeurs à la fois Gabor et mes réponses étaient des tableaux d'une dimension. Ils pourraient être transformés en vecteurs nommés en entourant l'objet par c () qui se double d'une concaténation et la contrainte à fonction vectorielle. Et comme ils se sont parfaitement acceptables pour rbinding ou accéder à « [ » selon les modalités et les résultats attendus retrun attendus des noms ().
La fonction retourne Tapply tableaux avec le nombre de dimensions dans l'argument d'index (s) et peuvent être combinés de manière très efficace pour les opérations de la matrice avec des objets de table. Je fais beaucoup de diviser par des sommes chefs d'accusation, ou compte par des sommes pour obtenir des statistiques significatives de la catégorie en 2, 3 ou 4 dimensions.