【问题标题】:How to fill a new dataframe column by conditional summing如何通过条件求和填充新的数据框列
【发布时间】:2017-06-03 12:22:04
【问题描述】:

我想通过对考虑多个条件的值求和来构建一个新变量(以及一个额外的条件,见下文)。在这里你可以看到 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 的解决方案...我只想要一个允许我返回正确值的公式在我的新专栏中。这是我的额外条件。为什么?这是因为我接下来要使用最复杂的公式构建其他变量,而不仅仅是一个总和。通过了解如何进行此类条件操作,我希望继续...

感谢您的帮助。

杰夫

【问题讨论】:

    标签: r


    【解决方案1】:

    你的意思是:

    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
    

    【讨论】:

    • 谢谢。第一个提案效果很好,但与 Roman 的提案有相同的限制。你的第二个在我看来是准确的,但不适用于我的数据集。我收到错误消息:“$&lt;-.data.frame(*tmp*, AZ_tx, value = c(96L, 24L, 84L, 12L, 中的错误:替换有 105 行,数据有 322”。
    • 这是真的。有可能克服它吗?其他想法?我最初宁愿添加一个参数,如“& df1$area == ??”在哪里 ??考虑到输出行,给出 df2$area 的相对值...
    • 非常感谢您的编辑。这是很不错的。但是,我不想重塑/更改数据框,因为我希望最后用更复杂的操作填充新列。承认我想一步创建“newvar2”,结果是将 Z1_sum 除以 Z2_sum 并乘以 100...
    【解决方案2】:

    只是基于您希望计入最终总和的 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
    

    【讨论】:

    • 谢谢罗曼。一次拍摄效果很好,但我不知道如何用一个以上的新列填充我的数据框 df2 。考虑到 Z1_sum 是我想填充 df2 数据框的许多新列(Z2_sum 等)之一,使用 agregate 函数在我看来,我必须构建许多中间数据框并稍后将其合并为一个...我错了吗?
    【解决方案3】:

    你可以使用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 动词应该很好解释,%&gt;% 是管道操作,从一个函数获取输出并将其作为下一个函数的第一个输入。 group_by 这里按area 列分组,所以当我们计算总和时(在summarize 中),它是每个区域组的总和。 filter 是数据的子集。

    【讨论】:

    • 谢谢。 dplyr 软件包很棒!
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 2021-07-25
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 2020-05-03
    相关资源
    最近更新 更多