2013-06-18 1 views
2

J'ai une trame de données commeComment mettre en œuvre correctement la fonction globale définie par l'utilisateur avec dcast

df<-data.frame(date=c(rep("1/27/2010",times=30)), 
      loc1=c(rep(9:13,each=6)), 
      loc2=c(rep(c("N","E","W"),each=2)), 
      loc3=c(rep(c(1,2))), 
      tr1=c(rep(c(0,1),each=15)), 
      tr2=c(0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1), 
      tr3=c(1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4), 
      Birth=c(sample(c("early","late"),30,replace=TRUE,prob=c(0.5,0.5))), 
      Species=c(rep(c("A","B"),times=15)), 
      Status=c(sample(c(0,1),30,replace=TRUE,prob=c(0.7,0.3)))) 

df<-rbind(df,df) 

Je veux faire des colonnes distinctes pour chaque valeur de NP3, avec des lignes définies par loc1, loc2, TR1, TR2 , tr3, naissance et espèces. Je veux «compter» les statuts de toutes les observations qui partagent ces valeurs et regrouper les comptes par loc3.

J'ai prévu d'utiliser dcast à partir du paquet reshape2.

J'ai écrit une fonction pour effectuer le 'compte' que je veux. Je suis nouveau à R et même si je suis sûr qu'il y a une fonction qui fait cela, je n'ai pas pu le trouver immédiatement et il m'a semblé utile d'essayer d'écrire le script moi-même, étant donné la simplicité de la tâche.

 d.count<-function(x){ 
    j=0 
    for (i in 1:length(x)) 
    if (is.na(x{i])){ 
     j<-j+0 
    }else if(x[i]==0){ 
     j<-j+1 
    } else if(x[i]==1){ 
     j<-j+0 
    } 
    return(j) 
} 

0s devrait augmenter le nombre et 1s et NA ne devraient pas.

Alors

df_1<-dcast(df,date+loc1+loc2+tr1+tr2+tr3+Birth+Species~loc3,value.var="Status",fun.aggregate=d.count) 

Je reçois l'erreur

Error in if (is.na(x[i])) { : argument is of length zero 

Ce qui me fait penser que je ne comprends pas comment dcast traite fun.aggregate ...

Merci pour l'aide! -JJE

Répondre

2

Pourquoi ne pas quelque chose comme cela en utilisant la fonction tabulate

require(reshape2) 
dcast(df, ... ~ loc3, value.var = "Status", fun.aggregate = tabulate) 

##   date loc1 loc2 tr1 tr2 tr3 Birth Species 1 2 
## 1 1/27/2010 9 E 0 0 1 early  A 0 0 
## 2 1/27/2010 9 E 0 0 1 early  B 0 0 
## 3 1/27/2010 9 N 0 0 1 early  B 0 0 
## 4 1/27/2010 9 N 0 0 1 late  A 0 0 
## 5 1/27/2010 9 W 0 0 1 early  B 0 0 
## 6 1/27/2010 9 W 0 0 1 late  A 0 0 
## 7 1/27/2010 10 E 0 1 2 late  A 0 0 
## 8 1/27/2010 10 E 0 1 2 late  B 0 2 
## 9 1/27/2010 10 N 0 0 1 late  A 0 0 
## 10 1/27/2010 10 N 0 1 2 late  B 0 2 
## 11 1/27/2010 10 W 0 1 2 late  A 0 0 
## 12 1/27/2010 10 W 0 1 2 late  B 0 0 
## 13 1/27/2010 11 E 0 1 2 late  A 0 0 
## 14 1/27/2010 11 E 1 0 3 early  B 0 2 
## 15 1/27/2010 11 N 0 1 2 early  B 0 0 
## 16 1/27/2010 11 N 0 1 2 late  A 0 0 
## 17 1/27/2010 11 W 1 0 3 late  A 0 0 
## 18 1/27/2010 11 W 1 0 3 late  B 0 2 
## 19 1/27/2010 12 E 1 0 3 early  B 0 0 
## 20 1/27/2010 12 E 1 0 3 late  A 0 0 
## 21 1/27/2010 12 N 1 0 3 early  A 2 0 
## 22 1/27/2010 12 N 1 0 3 early  B 0 2 
## 23 1/27/2010 12 W 1 0 4 early  A 0 0 
## 24 1/27/2010 12 W 1 1 4 early  B 0 0 
## 25 1/27/2010 13 E 1 1 4 early  B 0 0 
## 26 1/27/2010 13 E 1 1 4 late  A 0 0 
## 27 1/27/2010 13 N 1 1 4 late  A 0 0 
## 28 1/27/2010 13 N 1 1 4 late  B 0 2 
## 29 1/27/2010 13 W 1 1 4 early  A 0 0 
## 30 1/27/2010 13 W 1 1 4 early  B 0 2 

EDIT

Si vous voulez compter le nombre de 0 par exemple:

dcast(df, ... ~ loc3, value.var = "Status", 
     fun.aggregate = function(x) sum(x == 0, na.rm = TRUE)) 
+0

Wow, cela semble survenir mon problème, merci. Je ne comprends toujours pas comment dcast traite l'argument fun.agrgregate. Comment puis-je m'assurer que tabulate compte les zéros? en cours de tabulation sur un vecteur, me donne un vecteur et dcast nécessite l'argument fun.agrgregate pour donner un nombre. Comment puis-je compter les 1 avec tabulate (je dois faire cela ensuite ...) – user2498270

+0

@ user2498270 Si vous avez besoin d'une fonction qui comptera le nombre de 0 par exemple, vous pouvez faire quelque chose comme 'dcount <- function (x) sum (x == 0, na.rm = TRUE) '. Vous pouvez l'utiliser à la place de 'tabulate' et si vous voulez compter le nombre de 1, remplacez simplement sum (x == 0)' par sum (x == 1) '. J'espère que ça aide – dickoa

+0

C'est exactement ce dont j'avais besoin! Merci encore! – user2498270

Questions connexes