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 unique
và length
để 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á table
và 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
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