J'ai des données dans R qui ressemblent à ceci:
Cnty Yr Plt Spp DBH Ht Age
1 185 1999 20001 Bitternut 8.0 54 47
2 185 1999 20001 Bitternut 7.2 55 50
3 31 1999 20001 Pignut 7.4 71 60
4 31 1999 20001 Pignut 11.4 85 114
5 189 1999 20001 WO 14.5 80 82
6 189 1999 20001 WO 12.1 72 79
J'aimerais connaître la quantité d'espèces uniques (Spp) dans chaque comté (Cnty). "unique (dfname $ Spp)" me donne le nombre total d'espèces uniques dans la trame de données, mais j'aimerais les connaître par comté.
Toute aide est appréciée! Désolé pour le formatage étrange, ceci est ma première question sur SO.
Merci.
J'ai essayé de rendre vos échantillons de données un peu plus intéressants. Votre exemple de données ne contient actuellement qu’un seul "Spp" par "Cnty".
set.seed(1)
mydf <- data.frame(
Cnty = rep(c("185", "31", "189"), times = c(5, 3, 2)),
Yr = c(rep(c("1999", "2000"), times = c(3, 2)),
"1999", "1999", "2000", "2000", "2000"),
Plt = "20001",
Spp = sample(c("Bitternut", "Pignut", "WO"), 10, replace = TRUE),
DBH = runif(10, 0, 15)
)
mydf
# Cnty Yr Plt Spp DBH
# 1 185 1999 20001 Bitternut 3.089619
# 2 185 1999 20001 Pignut 2.648351
# 3 185 1999 20001 Pignut 10.305343
# 4 185 2000 20001 WO 5.761556
# 5 185 2000 20001 Bitternut 11.547621
# 6 31 1999 20001 WO 7.465489
# 7 31 1999 20001 WO 10.764278
# 8 31 2000 20001 Pignut 14.878591
# 9 189 2000 20001 Pignut 5.700528
# 10 189 2000 20001 Bitternut 11.661678
Ensuite, comme suggéré, tapply
est un bon candidat ici. Combinez unique
et length
pour obtenir les données que vous recherchez.
with(mydf, tapply(Spp, Cnty, FUN = function(x) length(unique(x))))
# 185 189 31
# 3 2 2
with(mydf, tapply(Spp, list(Cnty, Yr), FUN = function(x) length(unique(x))))
# 1999 2000
# 185 2 2
# 189 NA 2
# 31 1 1
Si vous êtes intéressé par une simple tabulation (pas de valeurs uniques), alors vous pouvez explorer table
et ftable
:
with(mydf, table(Spp, Cnty))
# Cnty
# Spp 185 189 31
# Bitternut 2 1 0
# Pignut 2 1 1
# WO 1 0 2
ftable(mydf, row.vars="Spp", col.vars=c("Cnty", "Yr"))
# Cnty 185 189 31
# Yr 1999 2000 1999 2000 1999 2000
# Spp
# Bitternut 1 1 0 1 0 0
# Pignut 2 0 0 1 0 1
# WO 0 1 0 0 2 0
Comme Justin l'a mentionné, l'agrégat est probablement ce que vous voulez. Si vous appelez votre bloc de données foo, les éléments suivants doivent vous donner ce que vous voulez, à savoir le nombre d'individus par espèce, en supposant que chaque rangée de noyer cendré représente un individu unique appartenant à l'espèce de noyer cendré. Remarque J'ai utilisé foo $ Age pour calculer la longueur du vecteur, c'est-à-dire le nombre d'individus (rangée) appartenant à chaque espèce, mais vous pouvez utiliser foo $ Ht ou foo $ DBH, etc.
aggregate(foo$Age, by = foo[c('Spp','Cnty')], length)
À votre santé,
Danny
Nous pouvons maintenant utiliser la fonction de décompte pour rendre cela plus facile.
tally(group_by(mydf, Spp, Cnty)) Spp Cnty n <fctr> <fctr> <int> 1 Bitternut 185 2 2 Bitternut 189 1 3 Pignut 185 2 4 Pignut 189 1 5 Pignut 31 1 6 WO 185 1 7 WO 31 2
with(mydf, tapply(Spp, list(Cnty, Yr),
FUN = function(x) length(unique(x))))
une requête unique ne fonctionne pas avec un ensemble de données volumineux.
set.seed(1)
mydf <- data.frame(
Cnty = rep(c("185", "31", "189"), times = c(5, 3, 2)),
Yr = c(rep(c("1999", "2000"), times = c(3, 2)),
"1999", "1999", "2000", "2000", "2000"),
Plt = "20001",
Spp = sample(c("Bitternut", "Pignut", "WO"), 10, replace = TRUE),
DBH = runif(10, 0, 15)
)
mydf
La fonction dplyr::count()
ressemble à une solution simple:
library(dplyr)
count(mydf, Spp, Cnty)
# A tibble: 7 x 3
# Spp Cnty n
# <fct> <fct> <int>
# 1 Bitternut 185 2
# 2 Bitternut 189 1
# 3 Pignut 185 2
# 4 Pignut 189 1
# 5 Pignut 31 1
# 6 WO 185 1
# 7 WO 31 2
Je voulais ajouter quelque chose à ce que A Handcart And Mohair a mentionné. Pour ceux d'entre vous qui souhaitent obtenir les résultats du code ci-dessous dans un bloc de données (utile dans R studio) ...
with(mydf, table(Spp, Cnty))
# Cnty
# Spp 185 189 31
# Bitternut 2 1 0
# Pignut 2 1 1
# WO 1 0 2
ftable(mydf, row.vars="Spp", col.vars=c("Cnty", "Yr"))
# Cnty 185 189 31
# Yr 1999 2000 1999 2000 1999 2000
# Spp
# Bitternut 1 1 0 1 0 0
# Pignut 2 0 0 1 0 1
# WO 0 1 0 0 2 0
Vous aurez besoin de mettre le modificateur as.data.frame.matrix devant votre code comme suit:
as.data.frame.matrix(with(mydf, table(Spp, Cnty)))
J'étais assez nouveau chez R quand je suis tombé sur ce poste et il m'a fallu beaucoup de temps pour le comprendre.
Une solution simple utilisant l'approche data.table
.
library(data.table)
output <- setDT(mydf)[ , .(count=.N) , by = .(Spp,Cnty)]
au cas où vous souhaiteriez remodeler la sortie dans un format de tableau plus agréable:
library(tidyr)
spread(data=a, key =Spp, count)
# Cnty Bitternut Pignut WO
# 1: 185 2 2 1
# 2: 189 1 1 NA
# 3: 31 NA 1 2
# or perhaps like this:
spread(data=a, key =Cnty, count)
# Spp 185 189 31
# 1: Bitternut 2 1 NA
# 2: Pignut 2 1 1
# 3: WO 1 NA 2