2013-04-23 9 views
10

で一意の値をカウント:R:私はこのようになりますRにデータを持っているカテゴリ

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 

を、私は、各郡(CNTY)で独特の種(SPP)の量を知っていただきたいと思います。 "unique(dfname $ Spp)"はデータフレーム内の固有の種の総数を示しますが、私はそれを郡が望んでいます。

ご協力いただきましてありがとうございます。奇妙な書式設定には申し訳ありませんが、これは初めての質問です。

ありがとうございました。

+0

SOへようこそ。あなたが何を試して、どこに問題があるのか​​をもっと分かち合うことで、より良い答えが得られます。しかし、あなたを始めさせるために、 'aggregate'や' tapply'のような関数が役に立ちます。 '?aggregate'を使って関数のヘルプテキストを見てください。 – Justin

答えて

2

Justinはおそらくあなたが望むものであると述べました。データフレームfooを呼び出すと、Butternutを持つ各行がButternut種に属する固有の個体を表すと仮定して、1つの種あたりの個体数です。私はそれぞれの種に属する個体数(行)すなわち、ベクトルの長さを計算するためのfoo $の年齢を使用しますが、あなたはFOO $のHtまたはFOO $ DBHなど

aggregate(foo$Age, by = foo[c('Spp','Cnty')], length) 

乾杯を使用することができ、

ダニー

15

サンプルデータを少し面白くしました。あなたのサンプルデータは現在、 "Cnty"ごとに1つのユニークな "Spp"しかありません。

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 

次のように、ここではtapplyが良い候補です。 uniquelengthを組み合わせて、探しているデータを取得します。あなたが(ない一意の値の)単純な集計に興味があるなら、あなたはtableftableを探索することができます

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 

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 
+0

アナンダ:非常に良い答え!あなたは、郡ごとに複数の種類の種が存在していると正しく仮定しました。これは正確に私が必要としていたものです。ご助力ありがとうございます。 –

+0

@KlausLouis、それを聞いてうれしい。これまたは他の回答が役に立つ場合は、それらをアップアップしたり、[受け入れる]ことを検討してください(http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)それら。ありがとう、そしてStack Overflowへようこそ! :) – A5C1D2H2I1M1N2O1R2T1

0
with(mydf, tapply(Spp, list(Cnty, Yr), 
    FUN = function(x) length(unique(x)))) 

独自のクエリは、大規模なデータセットで作業していない私は平均データは1000k行以上です。

0

私はハンドカットとモヘアールの言葉に言い添えたいと思っていました。 ...

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 

を(Rスタジオに役立つ)データフレームに以下のコードの結果を取得したいあなたのそれらのためにあなたは前にas.data.frame.matrix修飾子を配置する必要がありますあなたのコードのようにのように:

as.data.frame.matrix(with(mydf, table(Spp, Cnty))) 

私は、この投稿時に来たとき、私はRにかなり新しいだった、それはそれを把握するために私に長い時間がかかったので、私は私が共有したいと思いました。

0

data.tableアプローチを使用した簡単な解決策です。場合

library(data.table) 

output <- setDT(mydf)[ , .(count=.N) , by = .(Spp,Cnty)] 

あなたはよりよい表形式に出力を再構築したい:私たちは今、これを容易にするために集計関数を使用することができます

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 
0

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 
0
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 

dplyr::count()機能は、簡単な解決策のようになります。

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 
関連する問題