R中的条件求和(ddply,summary,sum)

时间:2017-06-28 22:39:04

标签: r dataframe plyr summarize

我有一个数据框,包含6个不同变量的观察值和每个变量的样本权重。我正在尝试使用ddplysummarize创建一个新数据框,其中六个变量中的一个变为第一列,其他变量是其他变量的加权和。

例如,我的数据框看起来像这样:

Location  A   B   C   D   SampleWeight
x1        2   1   4   3   .1
x1        4   3   4   2   .3
x2        2   3   7   3   .7
x2        4   3   4   3   .8
.....

我想创建一个数据框,每个位置只有一个值,然后将每列中每个条件的SampleWeights和总和相加。它看起来像这样:

Location   Total   A2   A4   B1   B3    C4   C7  ...
x1         0.4     .1   .3   .1   .3    .4   0.0
x2         1.5     .7   .8   0.0   1.5   .8   .7

这就是我试图去做的事情,我已经让总列工作了,但我不知道如何制作一个过滤器,使得sum只会查看另一行中具有特定值的行柱。我已经包含了一些我尝试过的东西:

newdf <- ddply(mydf, ~ `Location`, summarize, 
                total = sum(`SampleWeight`),
                A2 = sum(within(`SampleWeight`, A == "2")),
                A4 = sum(filter(mydf$SampleWeight, A == "4")),
                B1 = sum((mydf$B=="1")$sample_weight)
                ...
                )

有更简单的方法可以做到这一点吗?有没有一种很好的方法来制作这种文件管理器?

非常感谢!!

1 个答案:

答案 0 :(得分:0)

以下是使用dplyrtidyr的解决方案。生成数据:

library(dplyr)
library(tidyr)

df <- tibble(location     = c("x1", "x1", "x2", "x2"),
             A            = c(2, 4, 2, 4),
             B            = c(1, 3, 3, 3),
             C            = c(4, 4, 7, 4),
             D            = c(3, 2, 3, 3),
             SampleWeight = c(.1, .3, .7, .8))

然后:

res <- df %>%
  group_by(location) %>%
  mutate(total = sum(SampleWeight)) %>%
  gather(key = "letter", value = "number", A, B, C, D) %>%
  mutate(subgroup = paste0(letter, number)) %>%
  group_by(location, subgroup, total) %>%
  summarize(subgroup_total = sum(SampleWeight)) %>%
  spread(key = subgroup, value = subgroup_total) %>%
  mutate_all(function (x) ifelse(is.na(x), 0, x))

这可以分为四个部分:

  1. group_by位置并计算总SampleWeight
  2. gather将数据转换为长格式,并使用paste0连接以构建所需的子组(将成为列)
  3. group_by子组并计算SampleWeight的总和,然后将spread数据计算为宽格式
  4. NA替换为0
  5. 结果:

    res
      location total    A2    A4    B1    B3    C4    C7    D2    D3
    1       x1   0.4   0.1   0.3   0.1   0.3   0.4   0.0   0.3   0.1
    2       x2   1.5   0.7   0.8   0.0   1.5   0.8   0.7   0.0   1.5