如何通过条件求和填充新的数据帧列

时间:2017-06-03 12:22:05

标签: r

我想通过在考虑多个条件的情况下对值进行求和来构建一个新变量(以及额外的一个,见下文)。在这里你可以看到R代码直到我当前的问题。

# The raw dataframe
area <- c("A", "A", "B", "A", "C", "B", "A", "B", "A", "C")
varclass <- c("Z1", "Z1", "Z1", "Z2", "Z1", "Z1", "Z2", "Z1", "Z2", "Z2")
count <- c(45, 56, 2, 8, 345, 3, 98, 2, 6, 9)

df1 <- data.frame(area,
                  varclass,
                  count,
                  stringsAsFactors = FALSE)
df1
# See how df1 looks like...
#    area varclass count
#1     A       Z1    45
#2     A       Z1    56
#3     B       Z1     2
#4     A       Z2     8
#5     C       Z1   345
#6     B       Z1     3
#7     A       Z2    98
#8     B       Z1     2
#9     A       Z2     6
#10    C       Z2     9

# Building the final dataframe

df2 <- data.frame(unique(df1$area),
                  stringsAsFactors = FALSE)
names(df2)[1] <- "area"
# See how df2 looks like...
#   area
#1    A
#2    B
#3    C 

# The new variable to build

df2$Z1_sum <- sum(df1[df1$varclass == "Z1" & df1$area == df2$area,]$count)
# doesn't work

# See what I hope
#   area  Z1_sum
#1    A     101
#2    B      7
#3    C     345

正如您在最后一行中所看到的,我想在df2数据库中构建一个新变量Z1_sum。 Z1_sum是来自df1数据库的计数总和,其中varclass = "Z1"df1$area符合df2$area当前行的值(在MS Excel中,这意味着使用LC1或$ A2单元ID)。

请考虑一下这样的事实:我没有找到涉及通过使用条件分组或dcast函数从df1直接构建df2的解决方案...我只想要一个允许我的公式在我的新列中返回正确的值。这是我的额外条件。为什么?这是因为我接下来用最复杂的公式构建其他变量而不仅仅是一个总和。通过了解如何进行这样的条件操作,我希望继续......

感谢您的帮助。

杰夫

3 个答案:

答案 0 :(得分:0)

你的意思是:

df2 <- setNames(
                aggregate(
                          count ~ area,
                          df1[df1$varclass == "Z1", ],
                          sum
                          ),
                c("area", "Z1_sum")
               )
df2
  area Z1_sum
1    A    101
2    B      7
3    C    345

df2$Z1_sum <- aggregate(count ~ area, df1[df1$varclass == "Z1", ], sum)$count

编辑以解决您的评论。

尝试:

df2 <- aggregate(
                 count ~ area + varclass,
                 df1,
                 sum
                )

将以“长”格式为您提供数据:

df2
  area varclass count
1    A       Z1   101
2    B       Z1     7
3    C       Z1   345
4    A       Z2   112
5    C       Z2     9

现在您需要使用以下内容将其重新整形为“宽”格式:

df2 <- xtabs(count ~ area + varclass, df2)
    varclass
area  Z1  Z2
   A 101 112
   B   7   0
   C 345   9

或:

df2 <- reshape(df2, idvar = "area", timevar = "varclass", direction = "wide")
  area count.Z1 count.Z2
1    A      101      112
2    B        7       NA
3    C      345        9

答案 1 :(得分:0)

根据您想要计算的最终总和中的Z *,进行子集化。

df1Z1 <- df1[df1$varclass %in% c("Z1"), ]
aggregate(count ~ area, data = df1Z1, FUN = sum)

  area count
1    A   101
2    B     7
3    C   345

答案 2 :(得分:0)

您可以使用dplyr

获得所需的结果
library(dplyr)

df2 <- group_by(df1, area) %>% 
  filter(varclass == "Z1") %>% 
  summarize(Z1_sum = sum(count)) %>% 
df2
#> # A tibble: 3 x 2
#>    area Z1_sum
#>   <chr>  <dbl>
#> 1     A    101
#> 2     B      7
#> 3     C    345

dplyr动词应该是非常明确的解释,%>%是管道操作,从一个函数获取输出并使其成为下一个函数的第一个输入。 group_by此处area列分组,因此当我们计算总和(summarize)时,它就是每个区域组的总和。 filter子集数据。