2012-01-17 6 views
2

J'utilise le paquet sqldf dans R et j'essaie de trouver le nombre de valeurs qui sont 1 et 2 dans une seule colonne. Mes données ressemble:Comptage des valeurs dans une seule colonne

> head(d) 
     bid status 
1 201-300  1 
2 201-300  1 
3 901-1000  2 
4 601-700  1 
5 801-900  1 
6 801-900  2 

Je suis en train de trouver la statut quand il est égal à 1 et le nombre de statut quand il est égal à 2, puis les ai dans deux colonnes distinctes.

Donc, en utilisant le paquet sqldf dans R, je courais le code suivant:

sqldf("SELECT bid, SUM(IF(status='2', 1,0)) AS 'won', SUM(IF(status='1', 1,0)) AS 'lost', COUNT(bid) FROM d GROUP BY bid") 

Cependant, je reçois le message d'erreur suivant.

Error in sqliteExecStatement(con, statement, bind.data) : 
    RS-DBI driver: (error in statement: no such function: IF) 

Est-ce impossible avec le paquet sqldf? Existe-t-il un moyen d'obtenir les résultats souhaités avec une autre commande sql dans R? (Ou avec plyr, remodeler, ou tout autre outil R)

+1

utilisez 'table (d $ status)' – Andrie

+0

Votre requête est une requête mysql valide. est cette question à propos de mysql? –

Répondre

1

Puisque vous avez dit que vous pourriez être intéressé par une solution plyr, je peux donner que:

ddply(d, .(bid), summarise, won = sum(status==2), 
          lost = sum(status==1), count = length(bid)) 
+0

+ 1 Merci! La syntaxe de sql a toujours été plus intuitive pour moi, mais j'aime cette solution et je devrai en savoir plus sur plyr. – ATMathew

4

Le IF est afaik une syntaxe spécifique MySQL alors que l'erreur indique que vous parlez à une base de données SQLite.

Vous devez remplacer le IF par un CASE qui fonctionnerait sur tous les DMBS conformes à la norme ANSI SQL-92.

SELECT bid 
     , SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS won 
     , SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS lost 
FROM d 
GROUP BY 
     bid 
+2

+1 - Bonne prise sur le RDBMS – JNK

2

Le SQL normal serait d'utiliser CASE et SUM - Je ne fais pas MySQL, mais je suppose que ce doit être une syntaxe valide:

SELECT SUM(CASE WHEN Status = '2' THEN 1 ELSE 0 END) as 'won', 
     SUM(CASE WHEN Status = '1' THEN 1 ELSE 0 END) as 'lost', 
... 
+0

+1 - La même idée semble-t-il. –

2

Edit: la question était étiqueté mysql mais je ne suis pas sûr que ce soit le cas

Regardez MySQL Control Flow Functions. Vous pouvez utiliser la IF construction (spécifique MySQL) ou CASE WHEN (ANSI compatible) opérateur:

SELECT 
bid, 
SUM(IF(status = 2, 1, 0)) AS `won`, 
SUM(IF(status = 1, 1, 0)) AS `lost`, 
COUNT(bid) 
FROM d 
GROUP BY bid 


SELECT 
bid, 
SUM(CASE status WHEN 2 THEN 1 ELSE 0 END) AS `won`, 
SUM(CASE status WHEN 1 THEN 1 ELSE 0 END) AS `lost`, 
COUNT(bid) 
FROM d 
GROUP BY bid 
+1

+1 Maintenant, je voudrais penser que * grands esprits se ressemblent *

+1

grands esprits tapez plus vite je suppose :) –

0

essayez ceci:

select count(bid) as 'bid_status_1' from d where bid_status = 1 union select count(bid) as 'bid_status_2'from d where bid_status = 2 
+0

Cela ne fonctionnera pas, car vous avez différentes colonnes dans les ensembles haut et bas ... – JNK

+0

@Tuong - Cela retournerait 2 enregistrements au lieu d'un. Il pourrait être fait fonctionner si vous ajoutez une colonne fictive, enveloppez ceci dans une sous-sélection, groupez dessus et prenez soin des NULL. –

+1

merci pour votre avis, je vais chercher plus sur ce sujet ... –

1

if est pas valide SQLite syntax. Essayez ceci:

> sqldf("select bid, sum(status=1) lost, sum(status=2) won, count(*) count 
+ from d group by bid") 
     bid lost won count 
1 201-300 2 0  2 
2 601-700 1 0  1 
3 801-900 1 1  2 
4 901-1000 0 1  1 
Questions connexes