【问题标题】:R: grouping/splitting a dataset by categories in combination with apply.weekly()R:结合 apply.weekly() 按类别对数据集进行分组/拆分
【发布时间】:2012-01-27 20:06:07
【问题描述】:

简介

我还不是 R 专家,所以请原谅我可能应该不好意思问的另一个问题。在another question,我在stackoverflow 上询问了一些关于如何将xts 对象的不规则每日数据聚合为每周值的非常有用的cmets apply.weekly() 函数。不幸的是,我没有找到像 tapply()ddply()by()aggregate() 这样的函数,它允许按与 apply.weekly() 函数一起使用的类别进行拆分。

我的数据

这是我的示例数据集。我已经在另一个问题中发布了。出于说明目的,我也冒昧地在此处发布:

example <- as.data.frame(structure(c(" 1", " 2", " 1", " 2", " 1", " 1", " 2", " 1", " 2", 
" 1", " 2", " 3", " 1", " 1", " 2", " 2", " 3", " 1", " 2", " 2", 
" 1", " 2", " 1", " 1", " 2", NA, " 2", NA, NA, " 1", " 3", " 1", 
" 3", " 3", " 2", " 3", " 3", " 3", " 2", " 2", " 2", " 3", " 3", 
" 3", " 2", " 2", " 3", " 3", " 3", " 3", " 1", " 2", " 1", " 2", 
" 2", " 1", " 2", " 1", " 2", " 2", " 2", " 3", " 1", " 1", " 2", 
" 2", " 3", " 3", " 2", " 2", " 1", " 2", " 1", " 1", " 2", NA, 
" 2", NA, NA, " 1", " 3", " 2", " 3", " 2", " 0", " 3", " 3", 
" 3", " 2", " 0", " 2", " 3", " 3", " 3", " 0", " 2", " 2", " 3", 
" 3", " 0", "12", " 5", " 9", "14", " 5", "tra", "tra", "man", 
"inf", "agc", "07-2011", "07-2011", "07-2011", "07-2011", "07-2011" 
), .indexCLASS = c("POSIXlt", "POSIXt"), .indexTZ = "", class = c("xts", 
"zoo"), .indexFORMAT = "%U-%Y", index = structure(c(1297642226, 
1297672737, 1297741204, 1297748893, 1297749513), tzone = "", tclass = c("POSIXlt", 
"POSIXt")), .Dim = c(5L, 23L), .Dimnames = list(NULL, c("rev_sit", 
"prof_sit", "emp_nr_sit", "inv_sit", "ord_home_sit", "ord_abr_sit", 
"emp_cost_sit", "usage_cost_sit", "tax_cost_sit", "gov_cost_sit", 
"rev_exp", "prof_exp", "emp_nr_exp", "inv_exp", "ord_home_exp", 
"ord_abr_exp", "emp_cost_exp", "usage_cost_exp", "tax_cost_exp", 
"gov_cost_exp", "land", "nace", "index"))))

“rev_sit”、“prof_sit”、“emp_nr_sit”、“inv_sit”、“ord_home_sit”、“ord_abr_sit”、“emp_cost_sit”、“usage_cost_sit”、“tax_cost_sit”、“gov_cost_sit”、“rev_exp”、 “prof_exp”、“emp_nr_exp”、“inv_exp”、“ord_home_exp”、“ord_abr_exp”、“emp_cost_exp”、“usage_cost_exp”、“tax_cost_exp”、“gov_cost_exp”、

参考调查中的问题。有“1”、“2”、“3”三种回答可能性代码。

“土地”、“nace”

分别是具有 16 个和 8 个独特因素的类别。

我的目标 我的目标是为“nace”和“land”中的类别因素的每个组合每周计算“1”、“2”和“3”的出现次数。我的想法是预先为每个回答可能性 {1,2,3} 创建二进制向量(example_1,example_2,example_2),然后应用类似:

apply.weekly(example_1, function(d){ddply(d,list(example$nace,example$land),sum)})

但这不适用于ddplyaggregateby 等。

我的目标

我最初的非专业工作不是创建时间序列,而是创建一个日期向量example$date,通过%V 将给定的时间列编码为每周一次,然后使用即:

tapply(example_1[,5], list(example$date,example$nace,example$land),sum)

当然,对于上面显示的 20 个问题中的每一个,我都必须这样做。然后我得到例如example_1:

第 1 周,nace1.land1,nace1.land2,nace1.land3,...,nace1.land16,nace2.land1,..,nace8.land16 第 2 周,nace1.land1,nace1.land2,nace1.land3,...,nace1.land16,nace2.land1,...,nace8.land16 ... ... 周,nace1.land1,nace1.land2,nace1.land3,...,nace1.land16,nace2.land1,..,nace8.land16

我必须对 2 (example_2) 和 3 (example_3) 做同样的事情,这对于 20 个问题中的每一个问题都会产生所有 16*8*3*20=7680 列。这种极端情况,另外使用这种方法,产品不是时间序列,因此不能按周正确排序。

总结

所以任何人都可以教我或给我一个提示如何将函数 apply.weekly()tapply()ddply()by()split()unstack() 等函数结合使用,或者任何其他方法来实现如上所述的分组。每一个提示都非常感谢。我已经在考虑放弃我的 R 实验并改回 stata 时感到很沮丧所以请帮助我!

【问题讨论】:

  • 我不敢相信你在同一个句子中使用了“Stata”和“intuitive”(没有否定)......
  • @DWin:我认为这取决于你想做什么。但是在 stata 中,你有一个 by() 函数,它只是给出 sum b 一个特定索引,而不直接折叠。因此,对于一周内的所有日期,您的值都相同。
  • require(xts) 错误消失。
  • @DWin:是的,example$index 这个东西只是一个变通方法。实际上我会发现使用 week.apply 会更好...
  • (删除了我关于错误的 cmets。)您应该澄清您是否希望这些计数适用于所有问题或每个问题单独。如果您使用更少的列创建测试用例,但使用同一周和 1/2/3 级别发生的一些日期和数据,这可能会有所帮助。

标签: r time-series xts categorization


【解决方案1】:

非常感谢您的帮助。与此同时,我正忙于其他一些事情,但现在我又开始解决我的问题了,在你们伟大的 cmets 的帮助下,我找到了解决方案:

我放弃了直接使用时间序列,将这一步推迟到我的分析结束。因此我采用日期向量并将其转换为周:

图书馆(ISOweek) d$index

(因为我使用的是 Windows,所以我使用 ISOweek 执行此操作)

然后我使用tapply 和lapply 的组合。以下函数计算每个日历周 (d$index = t[[22]]) 以及两个分类列 t[[21]]、t[ [22]]。在同一步骤中,整个事物都被转换为一个数据框:

groupweeksums

==>x 代表特定列,t 代表数据框(否则我不知道该怎么做,因为有时我必须在数据框的另一处处理一列,我想避免大量打字);如果 d 是数据框,则:

df

为了我不必对所有 20 个问题重复此过程,请使用 lapply:

df

这为我提供了一个漂亮的数据框,其中包含我进一步分析所需的一切。感谢您的帮助,在您的帮助下,我离解决方案越来越近了!!!

附:我还将这个答案发布到我在 stackoverflow 上发布的另一个问题,该问题与这个问题相关。我希望这没有问题或违反这里的任何规则。

【讨论】:

    【解决方案2】:

    我会按照您的建议添加一个“星期”列,但在处理之前将数据转换为高格式 - 如果需要,您可以在之后将其转换回时间序列。

    library(reshape2)
    d <- melt(example, id.vars=c("land", "nace", "index"))
    # You apparently want one of the followings
    dcast( d, land + nace + index ~ value, length )
    dcast( d, land + nace + index + variable ~ value, length )
    dcast( d, land + nace + index ~ variable + value, length )
    

    同样,你可以使用ddply:

    library(plyr)
    d <- melt(example, id.vars=c("land", "nace", "index"))
    ddply( d, 
      c("land", "nace", "index", "value"), 
      summarize, 
      number=length(value)  # The argument "value" does not play any role
    )
    

    您的 index 列包含当年的周数 (%Y-%U):这仅在所有日期都在同一日历年内有效。使用实际日期而不是周数可能更安全,例如,本周开始时的星期日 - 它还可以更容易地将结果转换为时间序列。

    week_start <- function(u) as.Date(u) - as.numeric(format(u, "%u"))
    example$index <- weekstart( as.POSIXct(rownames(example)) )
    # The following may also work.
    example$index <- format( as.POSIXct(rownames(example)), "%G-%V" )
    

    【讨论】:

    • 非常感谢!我将在当天晚些时候尝试此解决方案并报告我的成功!最好的问候,安德烈亚斯
    • 对不起!我还没有时间测试它。我现在有点着急。但我会尽快报告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 2013-11-22
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多