1

我正在尝试创建(键,值)对的聚合列表:

 d <- data.frame(key.1 = c(1,1),
                 val.1  = c(100,100),
                 key.2 = c(1,1),
                 val.2  = c(100,100),
                 key.3 = c(2,3),
                 val.3 = c(100,100))

key.1 val.1 key.2 val.2 key.3 val.3
    1   100     1   100     2   100
    1   100     1   100     3   100

我希望结果是:

key.1 val.1 key.2 val.2
    1   200     2   100
    1   200     3   100

这意味着 (1,100) 和 (1,100) 基于公共 1 聚合,它们的值总和为 200。第一行的 (2,100) 和第二行的 (3,100) 保持原样,因为有不是与另一对的公共密钥。

这个问题不同,在我的场景中,我必须分别聚合我的数据框的每一行。目前我只是逐行迭代,并为每一行使用“聚合”。有更聪明的方法吗?

4

2 回答 2

2

这是一种解决方案,可为您提供所需的值,尽管格式与您在示例输出中指定的格式略有不同:

  1. 创建一个基于 的“ID” rownames,因为您希望最后按行聚合...

    d$ID <- rownames(d)
    
  2. 使用将您的数据从“宽”格式转换为“长”格式reshape

    temp <- reshape(d, direction = "long", idvar="ID", 
                    varying = setdiff(names(d), "ID"))
    
    temp
    #     ID time key val
    # 1.1  1    1   1 100
    # 2.1  2    1   1 100
    # 1.2  1    2   1 100
    # 2.2  2    2   1 100
    # 1.3  1    3   2 100
    # 2.3  2    3   3 100
    
  3. 用于aggregate通过行 (ID) 和键 (key) 的组合来计算总和。此外,根据原始 ID 的“组”创建第二个“ID”。

    temp1 <- aggregate(val ~ ID + key, temp, sum)
    temp1 <- within(temp1, {
      ID2 <- ave(ID, ID, FUN = seq_along)
    })
    temp1
    #   ID key val ID2
    # 1  1   1 200   1
    # 2  2   1 200   1
    # 3  1   2 100   2
    # 4  2   3 100   2
    
  4. 再次使用reshape回到“宽”形式:

    reshape(temp1, direction = "wide", idvar="ID", timevar="ID2")
    #   ID key.1 val.1 key.2 val.2
    # 1  1     1   200     2   100
    # 2  2     1   200     3   100
    
于 2013-06-23T10:29:31.413 回答
0

为此,数据首先需要转换为“整洁”的格式。每个键和每个 val 实际上是同一个变量,您希望按键和另一个变量列进行聚合,该变量未显式编码。数据应该这样排列:

d <- data.frame(key = c(1,1,1,1,2,3), 
             val = c(100,100,100,100,100,100), 
             keycol = c(1,1,2,2,3,3))

这使

  key val  keycol
#   1 100       1
#   1 100       1
#   1 100       2
#   1 100       2
#   2 100       3
#   3 100       3

现在只需按key和聚合keycol即可获得所需的结果。我喜欢dplyr

library(dplyr)
d %>% group_by(key, keycol) %>% summarise(sum(val))

这会以正确的形式给出您想要的结果。

     key  keycol sum(val)
   (dbl)   (dbl)    (dbl)
#1     1       1      200
#2     1       2      200
#3     2       3      100
#4     3       3      100
于 2016-04-17T12:52:53.633 回答