【问题标题】:yet another aggregation又一个聚合
【发布时间】:2013-01-11 09:56:02
【问题描述】:

(对不起,如果标题不是很丰富:我不知道如何更好地定义这个问题)

我的数据格式如下:

在每个组中,我有一个 pre 值和一个或两个 post 值。我想将此表转换为以下内容:

我正在考虑将数据分组为:

aggregate(mydata, by = group, FUN = myfunction)

ddply(mydata, .(group), .fun = myfunction)

并在我的函数中处理每个组的元素。但我不知道该怎么做,因为我需要同时将typevalue 传递给我的函数。有没有更好的方法来做到这一点?

更新:快速而肮脏的示例数据集:

mydata <- data.frame(group = sample(letters[1:5], 10, replace = TRUE), 
                     type = sample(c("pre", "post"), 10, replace = TRUE), 
                     value = rnorm(10))

【问题讨论】:

  • 截图真的没用。您能否发布一些示例数据,我们可以将其复制并粘贴到 R 会话中进行处理。
  • 啊,对不起,你是对的。请稍等,我将附上示例数据。
  • 我会说使用 reshape2 包中的 dcast(),但你在 C 组中有那个讨厌的 post2。
  • 谢谢,我去看看 dcast。但是,一般来说 - 没有办法将子集的多个变量传递给用户的函数?这对我来说会容易得多:然后我会简单地返回一个包含每个子集的“pre”、“post1”和“post2”的列表......
  • @VasilyA,另一个提示,当发布使用随机数生成器的示例数据时,请务必在代码前使用set.seed()。这将使每个人都在使用相同的数据。

标签: r aggregate reshape


【解决方案1】:

试试这样的:

mydf <- data.frame(group = c("A", "A", "B", "B",
                             "C", "C", "C", "D",
                             "D", "E", "E"),
                   type = c("pre", "post", "pre",
                            "post", "pre", "post",
                            "post", "pre", "post",
                            "pre", "post"),
                   value = 1:11)

times <- with(mydf, ave(value, group, type, FUN = seq_along))
xtabs(value ~ group + interaction(type, times), mydf)
#      interaction(type, times)
# group post.1 pre.1 post.2 pre.2
#     A      2     1      0     0
#     B      4     3      0     0
#     C      6     5      7     0
#     D      9     8      0     0
#     E     11    10      0     0

或者:

times <- with(mydf, ave(value, group, type, FUN = seq_along))  
mydf$timevar <- interaction(mydf$type, times)
reshape(mydf, direction = "wide", idvar = "group", 
        timevar="timevar", drop="type")
#    group value.pre.1 value.post.1 value.post.2
# 1      A           1            2           NA
# 3      B           3            4           NA
# 5      C           5            6            7
# 8      D           8            9           NA
# 10     E          10           11           NA

在这两种解决方案中,关键是创建一个“时间”变量,该变量由“类型”和可以使用ave 创建的序列变量的组合表示。

为了完整起见,这里是来自“reshape2”的dcast

times <- with(mydf, ave(value, group, type, FUN = seq_along))
library(reshape2)
dcast(mydf, group ~ type + times)
#   group post_1 post_2 pre_1
# 1     A      2     NA     1
# 2     B      4     NA     3
# 3     C      6      7     5
# 4     D      9     NA     8
# 5     E     11     NA    10

【讨论】:

  • 您可以将xtabs 的输出包装在as.data.frame.matrix 中以获取data.frame。对于这个特定问题,我更喜欢 reshape 输出,因为它将值显示为 NA,而不是 0
  • @AnandaMahto 你为什么打电话给“with”? ave 调用还不够吗?
  • @AdityaSihag,只有在您当前环境中可以直接访问“值”、“组”和“类型”时才有效,除非您使用过 attach,否则它们不能使用,我不喜欢这样做。另一个选项是ave(mydf$value, mydf$group...,它需要大量额外的输入,因此更容易出错。
猜你喜欢
  • 1970-01-01
  • 2021-05-11
  • 2013-07-10
  • 2014-12-11
  • 2023-03-28
  • 2020-12-31
  • 2015-01-04
  • 2018-08-12
  • 2013-06-17
相关资源
最近更新 更多