1

我不太明白如何使用 dplyr 包在 R 中构建一些分组和摘要。

通过下面的可重现示例,我尝试首先按 (PN,GOT,HID) 分组以计算 PC1 的不同实例。然后,我根据第二个分组,按 (PN,GOT) 重新分组,对 PC1 的不同实例求和。这个过程似乎适用于总和,除了对于平均值(TC),当我希望通过(PN,GOT)的分组看到平均值时,我得到了整个数据帧的平均值。我缺少什么来获得(PN,GOT)的那些手段,同时又不失去我建立的 PC1 的总和?我会很感激我在这里出错的地方的一些解释。

PN<- c("Mazda","Mazda","Datsun","Hornet","Hornet","Valiant","Duster","Merc","Merc","Merc","Merc","Merc",
       "Merc","Merc","Fiat","Honda","Toyota","Toyota","Dodge","AMC","Fiat")
GOT<- c("A","A","B","C","C","A","D","B","B","B","B","B","B","B","A","D","B","B","C","E","A")
HID<- c("Mazda_H1","Mazda_H1","Datsus_H1","Hornet_H1","Hornet_H2","Valiant_H1","Duster_H1","Merc_H1","Merc_H1","Merc_H1",
        "Merc_H2","Merc_H2","Merc_H3","Merc_H4","Fiat_H1","Honda_H1","Toyota_H1","Toyota_H2","Dodge_H1","AMC_H1","Fiat_H1")
PIC<- c("BB","BB","BB","BB","AA","AA","AA","BA","BA","BA",
        "AA","BB","BB","BB","BB","AA","AA","AA","BA","BA","BA")
TC <- c(110,110,93,175,175,105,245,62,62,62,62,62,62,62,33,52,97,97,150,150,33)
Int <- c(16.46,17.02,18.61,19.44,17.02,20.22,15.84,20.00,22.90,18.30,18.90,
         17.40,17.60,18.00,19.47,18.52,19.90,20.01,16.87,17.30,18.90)
PC1<- c("", "","G1","C1","","G1","", "G1","G1","C1","C1","","","","Z1","Z1","Z1","Z1","","","G1")

df<-data.frame(PN,GOT,HID,PIC,TC,Int,PC1)

df

df%>% filter(PC1!="") %>%
  group_by(PN, GOT, HID) %>%
  summarize(new = n_distinct(PC1)) %>%
  group_by(PN, GOT) %>%
  mutate(TOT_new = sum(new),
            meanTC = mean(TC))

我认为我正在寻找的答案是这样的:

       PN    GOT        HID   TOT_new meanTC
   <fctr> <fctr>     <fctr>   <int>  <dbl>
1  Datsun      B  Datsus_H1     1     93
2    Fiat      A    Fiat_H1     2     33
3   Honda      D   Honda_H1     1     52
4  Hornet      C  Hornet_H1     1    175
5    Merc      B    Merc_H1     3     62
6  Toyota      B  Toyota_H1     2     97
7 Valiant      A Valiant_H1     1    105

或者至少是这样的:

       PN    GOT        HID   new TOT_new meanTC
   <fctr> <fctr>     <fctr> <int>   <int>  <dbl>
1  Datsun      B  Datsus_H1     1       1     93
2    Fiat      A    Fiat_H1     2       2     33
3   Honda      D   Honda_H1     1       1     52
4  Hornet      C  Hornet_H1     1       1    175
5    Merc      B    Merc_H1     2       3     62
6    Merc      B    Merc_H2     1       3     62
7  Toyota      B  Toyota_H1     1       2     97
8  Toyota      B  Toyota_H2     1       2     97
9 Valiant      A Valiant_H1     1       1    105
4

3 回答 3

2

正如@r2evans 所评论的,您获得全局平均值的原因是在第一个汇总阶段删除了TC列。除了join评论中建议的选项外,您还可以TC通过计算两个中间变量在第一个汇总阶段将列信息向前传递:

df %>% filter(PC1 != "") %>%

    group_by(PN, GOT, HID) %>%
    # create two columns with the sum and length of TC in each group which you can use later
    # for average calculation
    summarize(new = n_distinct(PC1), n = n(), TC_sum = sum(TC)) %>%

    group_by(PN, GOT) %>%
    summarise(TOT_new = sum(new), meanTC = sum(TC_sum)/sum(n))

# Source: local data frame [7 x 4]
# Groups: PN [?]

#       PN    GOT TOT_new meanTC
#   <fctr> <fctr>   <int>  <dbl>
#1  Datsun      B       1     93
#2    Fiat      A       2     33
#3   Honda      D       1     52
#4  Hornet      C       1    175
#5    Merc      B       3     62
#6  Toyota      B       2     97
#7 Valiant      A       1    105
于 2017-02-27T03:59:31.450 回答
1

我们也可以使用data.table. 将'data.frame'转换为'data.table'( setDT(df)),在'i'( )中指定逻辑条件PC1 != "",按'PN'、'GOT'、'HID'分组,我们得到'PC1'lengthunique元素( ' new ' ) .N,每组的元素数(“TOT_new”和“meanTC”。分配不需要的列sumsumsumsumNULL

library(data.table)
setDT(df)[PC1 != "", .(new = uniqueN(PC1), n = .N, TC_sum = sum(TC)) ,.(PN, GOT, HID)
       ][, c("TOT_new", "meanTC") := .(sum(new), sum(TC_sum)/sum(n)) ,.(PN, GOT)
         ][, c("n", "TC_sum") := NULL][]
#        PN GOT        HID new TOT_new meanTC
#1:  Datsun   B  Datsus_H1   1       1     93
#2:  Hornet   C  Hornet_H1   1       1    175
#3: Valiant   A Valiant_H1   1       1    105
#4:    Merc   B    Merc_H1   2       3     62
#5:    Merc   B    Merc_H2   1       3     62
#6:    Fiat   A    Fiat_H1   2       2     33
#7:   Honda   D   Honda_H1   1       1     52
#8:  Toyota   B  Toyota_H1   1       2     97
#9:  Toyota   B  Toyota_H2   1       2     97
于 2017-02-27T05:13:05.367 回答
0

根据上面的一些评论,这是使其工作的一种方法。但它看起来是多余的。

df%>% filter(PC1!="") %>%
  group_by(PN, GOT, HID) %>%
  summarize(new = n_distinct(PC1),
            meanTC = mean(TC)) %>%
  group_by(PN, GOT) %>%
  mutate(TOT_new = sum(new),
         meanTC = mean(meanTC))%>%
  select(-HID)

       PN    GOT   new meanTC TOT_new
   <fctr> <fctr> <int>  <dbl>   <int>
1  Datsun      B     1     93       1
2    Fiat      A     2     33       2
3   Honda      D     1     52       1
4  Hornet      C     1    175       1
5    Merc      B     2     62       3
6    Merc      B     1     62       3
7  Toyota      B     1     97       2
8  Toyota      B     1     97       2
9 Valiant      A     1    105       1
于 2017-02-27T04:35:49.730 回答