2013-04-23 29 views
10

Tôi có dữ liệu trong R trông như thế này:R: Đếm giá trị duy nhất theo thể loại

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 

Tôi muốn biết số lượng loài duy nhất (SPP) trong mỗi quận (Cnty). "unique (dfname $ Spp)" cung cấp cho tôi tổng số các loài duy nhất trong khung dữ liệu, nhưng tôi muốn nó theo quận.

Mọi trợ giúp đều được đánh giá cao! Xin lỗi vì định dạng lạ, đây là câu hỏi đầu tiên của tôi về SO.

Cảm ơn.

+0

Chào mừng bạn đến SO. Chia sẻ thêm về những gì bạn đã thử và nơi bạn đang gặp sự cố sẽ mang lại câu trả lời tốt hơn. Tuy nhiên, để giúp bạn bắt đầu, các hàm như 'aggregate' và' tapply' là hữu ích. hãy nhớ xem văn bản trợ giúp từ một hàm bằng cách sử dụng '? aggregate'. – Justin

Trả lời

2

Như Justin đã đề cập tổng hợp có lẽ là những gì bạn muốn. Nếu bạn gọi foo khung dữ liệu của bạn, sau đó sẽ cung cấp cho bạn những gì bạn muốn, cụ thể là số cá thể trên mỗi loài giả định rằng mỗi hàng với Butternut đại diện cho một cá thể duy nhất thuộc về các loài butternut. Lưu ý tôi đã sử dụng foo $ Tuổi để tính toán độ dài của vectơ, tức là số lượng cá thể (hàng) thuộc mỗi loài, nhưng bạn có thể sử dụng foo $ Ht hoặc foo $ DBH, vv

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

Chúc mừng,

Danny

15

Tôi đã cố gắng làm cho dữ liệu mẫu của bạn thú vị hơn một chút. Dữ liệu mẫu của bạn hiện chỉ có một "Spp" duy nhất cho mỗi "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 

Tiếp theo, như được đề xuất, tapply là một ứng cử viên tốt tại đây. Kết hợp uniquelength để nhận dữ liệu bạn đang tìm kiếm.

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 

Nếu bạn quan tâm đến lập bảng đơn giản (không có giá trị duy nhất), sau đó bạn có thể khám phá tableftable:

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

Ananda: Câu trả lời rất hay! Bạn giả định chính xác rằng có tồn tại nhiều hơn một loại loài trên mỗi hạt, đó chính xác là những gì tôi cần đếm. Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn. –

+0

@KlausLouis, Rất vui khi được nghe. Nếu câu trả lời này hoặc bất kỳ câu trả lời nào khác hữu ích, hãy cân nhắc việc upvoting chúng và/hoặc [accepting] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) một trong chúng. Cảm ơn và chào mừng bạn đến với Stack Overflow! :) – A5C1D2H2I1M1N2O1R2T1

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

truy vấn duy nhất là không làm việc với tập hợp dữ liệu lớn i dữ liệu trung bình hơn 1000 nghìn hàng.

0

Tôi muốn thêm vào những gì mà Handcart và Mohair đã đề cập. Đối với những người bạn muốn để có được các kết quả của mã dưới đây vào một khung dữ liệu (hữu ích trong studio R) ...

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 

Bạn sẽ cần phải đặt các modifier as.data.frame.matrix trước của mã của bạn như vậy:

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

Tôi đã khá mới đối với R khi tôi đăng bài này và tôi mất nhiều thời gian để hiểu điều đó, vì vậy tôi nghĩ mình sẽ chia sẻ.

0

Một giải pháp đơn giản sử dụng phương pháp data.table.

library(data.table) 

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

trong trường hợp bạn muốn thay đổi hình dáng đầu ra sang một định dạng bảng đẹp hơn:

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

Bây giờ chúng ta có thể sử dụng chức năng kiểm đếm để làm cho dễ dàng hơn này.

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 

Chức năng dplyr::count() trông giống như một giải pháp đơn giản:

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