如何使用ddply过滤

How to filter using ddply

我有数据:

df<- data.frame(Plot = rep(rep(1:3,each = 2),3), Year = rep(1:3,each = 6), 
                D = rep(c(1,1,5,NA,2,2,2,1,5),2), HT = rep(c(NA,NA,NA,NA,3,2,NA,4,5),2))


   Plot Year  D HT
1     1    1  1 NA
2     1    1  1 NA
3     2    1  5 NA
4     2    1 NA NA
5     3    1  2  3
6     3    1  2  2
7     1    2  2 NA
8     1    2  1  4
9     2    2  5  5
10    2    2  1 NA
11    3    2  1 NA
12    3    2  5 NA
13    1    3 NA NA
14    1    3  2  3
15    2    3  2  2
16    2    3  2 NA
17    3    3  1  4
18    3    3  5  5

我知道在 plyr 包中使用 ddply() 可以让我计算每个 plot-year 组合中存在的数量

ddply(df, .(df[,"Plot"], df[,"Year"]), nrow)

但是,我还想确定存在多少行给定 HT 不是 NA(或者如果 D > 1)。我想将此信息作为新列附加到上面 ddply 的输出中。

有没有办法在 ddply 中使用 data.frame 的一个或多个列中的值的子集来对数据进行子集化?

更新:期望的输出

   Plot Year Count HaveHt
1     1    1     2     0
2     1    2     2     1
3     1    3     2     1
4     2    1     2     0
5     2    2     2     1
6     2    3     2     1
7     3    1     2     2
8     3    2     2     0
9     3    3     2     2

如果我们使用 plyr,则通过指定 summarise 来汇总列并获得逻辑向量的 sum,即 HT 的非 NA 元素(!is.na(HT)) 按列分组后 length

plyr::ddply(df, c("Plot", "Year"), summarise, n = length(HT), HaveHt = sum(!is.na(HT)))

同样可以用 dplyr

library(dplyr)
df %>%
    group_by(Plot, Year) %>% 
    summarise(Count = n(), HaveHt = sum(!is.na(HT)))
# A tibble: 9 x 4
# Groups: Plot [?]
#   Plot  Year Count HaveHt
#  <int> <int> <int>  <int>
#1     1     1     2      0
#2     1     2     2      1
#3     1     3     2      1
#4     2     1     2      0
#5     2     2     2      1
#6     2     3     2      1
#7     3     1     2      2
#8     3     2     2      0
#9     3     3     2      2