【问题标题】:Vector of SumIfs() in RR中 SumIfs() 的向量
【发布时间】:2018-03-08 18:47:39
【问题描述】:

我希望通过为每个观察创建一个条件平均值的均值向量来模仿 R 中 Excel 的 SumIfs() 函数。我见过很多使用aggregate()setDT() 来根据固定数量汇总数据框的示例。但是,我想根据数据框中每一行的可变输入创建这些摘要的向量。

这是我的数据示例:

> a <- c('c', 'a', 'b', 'a', 'c', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'b', 'a')
> b <- c(6, 1, 1, 2, 1, 2, 2, 4, 3, 3, 5, 5, 4, 6, 6)
> c <- c(69.9, 21.2, 37, 25, 65.9, 33.1, 67, 28.4, 36, 67, 22, 37.9, 62.3, 30, 25)
> df <- data.frame(cbind(a, b, c))
> df$b <- as.numeric(as.character(df$b))
> df$c <- as.numeric(as.character(df$c))
> df
   a b    c
1  c 6 69.9
2  a 1 21.2
3  b 1 37.0
4  a 2 25.0
5  c 1 65.9
6  b 2 33.1
7  c 2 67.0
8  a 4 28.4
9  b 3 36.0
10 c 3 67.0
11 a 5 22.0
12 b 5 37.9
13 c 4 62.3
14 b 6 30.0
15 a 6 25.0

我想添加第四列,df$d,它取 df$c 的平均值,其中 df$a == x &amp; y - 2 &lt;= df$b &lt; y 其中 xy 分别是 df$adf$b,对于正在计算的观测值。

手动操作,df$d 看起来像:

> df$d <- c(62.3, NA, NA, 21.2, NA, 37, 65.9, 25, 35.05, 66.45, 28.4, 36, 67, 37.9, 25.2)
> df
   a b    c     d
1  c 6 69.9 62.30
2  a 1 21.2    NA
3  b 1 37.0    NA
4  a 2 25.0 21.20
5  c 1 65.9    NA
6  b 2 33.1 37.00
7  c 2 67.0 65.90
8  a 4 28.4 25.00
9  b 3 36.0 35.05
10 c 3 67.0 66.45
11 a 5 22.0 28.40
12 b 5 37.9 36.00
13 c 4 62.3 67.00
14 b 6 30.0 37.90
15 a 6 25.0 25.20

我可以使用一个函数来自动执行此操作吗?感谢您的帮助!

【问题讨论】:

    标签: r excel aggregate user-defined-functions sumifs


    【解决方案1】:

    这可以使用 SQL 中的左自连接以直接的方式完成。这将连接到dfu 实例的每一行dfv 实例的每一行满足on 条件,然后对它们的c 值求平均值。

    library(sqldf)
    
    sqldf("select u.*, avg(v.c) as d
           from df u left join df v
           on u.a = v.a and v.b between u.b-2 and u.b-1
           group by u.rowid")
    

    给予:

       a b    c     d
    1  c 6 69.9 62.30
    2  a 1 21.2    NA
    3  b 1 37.0    NA
    4  a 2 25.0 21.20
    5  c 1 65.9    NA
    6  b 2 33.1 37.00
    7  c 2 67.0 65.90
    8  a 4 28.4 25.00
    9  b 3 36.0 35.05
    10 c 3 67.0 66.45
    11 a 5 22.0 28.40
    12 b 5 37.9 36.00
    13 c 4 62.3 67.00
    14 b 6 30.0 37.90
    15 a 6 25.0 25.20
    

    【讨论】:

    • 我实际上只是想弄清楚如何使用data.table 进行同样的连接。以前没遇到过sqldf,很酷。 (+1)
    • 感谢两位的帮助!这是完美的。
    【解决方案2】:

    你可以只使用一个循环来基本上只是准确地写出你是如何描述问题的:

    n <- nrow(df)
    d <- numeric(n)
    
    for (i in seq_len(n)) {
      x <- df$a[i]
      y <- df$b[i]
      d[i] <- with(df, mean(c[a == x & y - 2 <= b & b < y]))
    }
    
    all.equal(d, df$d)
    #> [1] TRUE
    

    我不喜欢这个解决方案,但我想不出一个简单的方法来做到这一点,因为由于b 的条件,所需的分组不会不相交。我很好奇是否有人想出一个更简洁的方法来做到这一点。

    【讨论】:

      猜你喜欢
      • 2014-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2021-12-25
      • 1970-01-01
      相关资源
      最近更新 更多