【问题标题】:Summing up values in one column based on unique values in another column根据另一列中的唯一值汇总一列中的值
【发布时间】:2019-02-18 02:36:25
【问题描述】:

我正在尝试根据 B 列中的唯一值添加 C 列中的值。例如,对于 B = 1,我想添加 C 列中的所有行,即 5+4+3=12。

A B C
1 1 5
2 1 4 
3 1 3
4 2 1
5 2 3

for(i in unique(df$B)){
  df$D = sum(df$C)  
}

另外,我想添加 B 列中每个数据出现的次数。

解决方案:

A B C D  E 
1 1 5 12 3
2 1 4 12 3
3 1 3 12 3
4 2 1 4  2
5 2 3 4  2

我的任务示例:

  docIdx newsgroup_ID  freq  
       1            1   768 
       2            1   125  
       3            1    29 
       4            1    51  
       5            1   198 
       6            1    34 
       7            1    64 
       8            2    35
       9            2    70
       10           2    45

【问题讨论】:

  • 能否请您提供您的预期输出?这听起来像是 aggregate 或 group_by/summarise 的工作。

标签: r aggregate variable-length


【解决方案1】:

在基础 R 中,您可以使用 ave

df[, c("D", "E")] <- with(df, sapply(c(sum, length), function(x) ave(C, B, FUN = x)))
df
#  A B C  D E
#1 1 1 5 12 3
#2 2 1 4 12 3
#3 3 1 3 12 3
#4 4 2 1  4 2
#5 5 2 3  4 2

或使用dplyr

library(dplyr)
df <- df %>%
    group_by(B) %>%
    mutate(D = sum(C), E = length(C))
df
## A tibble: 5 x 5
## Groups:   B [2]
#      A     B     C     D     E
#  <int> <int> <int> <int> <int>
#1     1     1     5    12     3
#2     2     1     4    12     3
#3     3     1     3    12     3
#4     4     2     1     4     2
#5     5     2     3     4     2

样本数据

df <- read.table(text =
    "A B C
1 1 5
2 1 4
3 1 3
4 2 1
5 2 3", header = T)

它适用于您修改后的数据

df <- read.table(text =
    "docIdx newsgroup_ID  freq
       1            1   768
       2            1   125
       3            1    29
       4            1    51
       5            1   198
       6            1    34
       7            1    64
       8            2    35
       9            2    70
       10           2    45", header = T)


df[, c("sum.freq", "length.freq")] <- with(df, sapply(c(sum, length), function(x) 
    ave(freq, newsgroup_ID, FUN = x)))
#   docIdx newsgroup_ID freq sum.freq length.freq
#1       1            1  768     1269           7
#2       2            1  125     1269           7
#3       3            1   29     1269           7
#4       4            1   51     1269           7
#5       5            1  198     1269           7
#6       6            1   34     1269           7
#7       7            1   64     1269           7
#8       8            2   35      150           3
#9       9            2   70      150           3
#10     10            2   45      150           3

这里ave(freq, newsgroup_ID, FUN = x) 通过newsgroup_ID 将函数x 应用于freq。

【讨论】:

  • 谢谢@maurits,但它没有包含在数据框中或被保存。如何做到这一点?
  • 基础 R 解决方案增加了两个新列;所以df 将包含新列;对于dplyr 解决方案,只需存储在一个新的data.frame 中,例如前缀为df.new &lt;- ...
  • 对不起,我不知道如何保存它。解决方案按照你的建议来了,但我仍然无法保存它。
  • 没有什么可保存的。正如我所说,在基本 R 解决方案中 df 将包含新列 "D" 和 "E";至于dplyr 解决方案,我已经进行了编辑; df &lt;- df %&gt;% ... 将覆盖 df 并添加两个新列。
  • 我的数据集没有得到答案,尽管它正在使用您提供的示例。例如:docIdx newsgroup_ID freq total number 1 1 1 768 844174 7504 2 2 1 125 844174 7504 3 3 1 29 844174 7504 4 4 1 51 844174 7504 5 5 1 198 844174 7504 6 6 1 34 844174 7504 7 7 1 64 844174 7504 ..它是对整个列求和,而与newsgroup_ID中的不同值无关
【解决方案2】:

您可以aggregate 然后merge 使用原始数据框的结果:

df <- read.table(text="A B C
1 1 5
2 1 4 
3 1 3
4 2 1
5 2 3", header = TRUE)

merge(df, aggregate(C ~ B, df, FUN = function(x) c(sum=sum(x), length=length(x))), by = "B")
#>   B A C.x C.y.sum C.y.length
#> 1 1 1   5      12          3
#> 2 1 2   4      12          3
#> 3 1 3   3      12          3
#> 4 2 4   1       4          2
#> 5 2 5   3       4          2

由reprex package (v0.2.1) 于 2019 年 2 月 18 日创建

【讨论】:

  • 显示错误“fix.by(by.y, y) 中的错误:'by' 必须指定唯一有效的列”
【解决方案3】:
B <- c(1,1,1,2,2)
C <- c(5,4,3,1,3)
x <- cbind(B,C)

sum <- 0
for (i in 1:nrow(x)) {
  if (x[i] == 1) {
    sum <-  x[i, 2] + sum 
  }
  sum
}

希望对你有帮助。

【讨论】:

  • 显示错误; [.data.frame(class_prior_newsgroup, i) 中的错误:选择了未定义的列此外:警告消息:1:在 if (class_prior_newsgroup[i] == 1) { 中:条件的长度 > 1,并且只使用第一个元素 2 : 在 if (class_prior_newsgroup[i] == 1) { : 条件的长度 > 1 并且只使用第一个元素 3: 在 if (class_prior_newsgroup[i] == 1) { : 条件的长度 > 1 并且只使用第一个元素
【解决方案4】:

如果你想使用循环条件做同样的逻辑

for (i in unique (df$B)){

  xx <- sum(df$C[df$B==i])

  yy <- length(df$C[df$B==i])

  df$D[df$B==i] <- xx

  df$E[df$B==i] <- yy
}
print(df)
  A B C  D E
1 1 1 5 12 3
2 2 1 4 12 3
3 3 1 3 12 3
4 4 2 1  4 2
5 5 2 3  4 2

【讨论】:

    【解决方案5】:
    B <- c(1,1,1,2,2)
    C <- c(5,4,3,1,3)
    x <- cbind(B,C)
    
    
    holder1 <- c()
    holder2 <- c()
    for (num in unique(x[,1])) {
      sum <- 0
      count <- 0
      for (i in 1:nrow(x)) {
        if (x[i] == num) {
          sum <-  x[i, 2] + sum
          count <- 1 + count
        }
      }
      print(count)
      holder1 <- c(holder1, rep(count, count))
      holder2 <- c(holder2, rep(sum, count))
    }
    x <- as.data.frame(x)
    x <- add_column(x, E = holder1, .after = "C")
    x <- add_column(x, D = holder2, .after = "C")
    
    
    > x
      B C  D E
    1 1 5 12 3
    2 1 4 12 3
    3 1 3 12 3
    4 2 1  4 2
    5 2 3  4 2
    

    注意: 确保我们有相同的变量。 (看懂代码) 我不知道高级功能,这就是我使用基本功能的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-15
      • 2015-08-03
      • 2021-03-16
      • 2020-02-08
      • 2023-02-23
      • 2021-04-29
      • 1970-01-01
      • 2021-08-03
      相关资源
      最近更新 更多