0

我正在努力寻找解决以下问题的有效解决方案:

我有一个大的操纵数据框,大约有 8 列和 80000 行,通常包括多种数据类型。如果满足大型数据框的条件,我想创建一个包含一列总和的新数据框。

想象一下原始数据框的头部是这样的。$years.raw 列表示公司测量了 x 年的数据。

> cbind(company.raw,years.raw,source,amount.inkg)
     company.raw years.raw source      amount.inkg
[1,] "C1"        "1"       "Ink"       "5"        
[2,] "C1"        "1"       "Recycling" "2"        
[3,] "C2"        "1"       "Coffee"    "10"       
[4,] "C2"        "1"       "Combusted" "15"       
[5,] "C2"        "2"       "Printer"   "14"       
[6,] "C2"        "2"       "Tea"       "18"   

我现在需要做的是创建一个新的数据框,根据某些字符串元素总结每家公司和每年的 $amount.inkg 列的值。我将字符串元素保存在下面的三个向量中。字符串元素是原始数据框中 $source 列的一部分。

> vector1 <- c("Tea","Coffee")
> vector2 <- c("Ink","Printer")
> vector3 <- c("Recycling","Combusted")

首选数据框将如下所示:

Company Year              amount.vector1    amount.vector 2 amount.vector 3
C1           1                 0             5                 2
C2           1                 10            0                15        
C2           2                 18            14                0

$amount.vector1 的一般方法是: 汇总每个公司和每年的 $amount.inkg 列的值,其中原始数据框列 $source== vector1 的字符串元素。列 $amount.vector2 相同,只是元素当然不同。

如果没有可用的值,则应添加“0”而不是 NA 错误。这需要对整个原始数据框架进行,其中包括大约 250 家公司,每家公司的数据为 1:8(差异很大)。

编辑:对于数据框,我需要每年每公司一行。

C1 Year 1  
C1 Year 2
C1 Year 3
C2 Year 1
C2 Year 2

我试图编写一个结合这些条件的函数,但我失败了。我对 R 很陌生,不知道如何链接这些条件并将它们应用于整个数据框。

4

2 回答 2

2

您的数据是“长格式”(多行公司、来源、年份……)

对于多个来源值,您希望汇总每个公司和年份的 amount.inkg。具体来说,您希望与“源”字段的条件进行聚合。

再次,请给我们可重现的例子。(谢谢乔西伯)。这是一个具有拆分-应用-组合(ddply)或逻辑索引的四行:

df = data.frame(company.raw = c("C1", "C1", "C2", "C2", "C2", "C2"),
                years.raw = c(1, 1, 1, 1, 2, 2),
                source = c("Ink", "Recycling", "Coffee", "Combusted", "Printer", "Tea"),
                amount.inkg = c(5, 2, 10, 15, 14, 18))

# OPTION 1. Split-Apply-Combine: ddply(...summarize) with a conditional on the data
require(plyr) # dplyr if performance on large d.f. becomes an issue
ddply(df, .(company.raw,years.raw), summarize,
    amount.vector1=sum(amount.inkg[source %in% c('Tea','Coffee')]),
    amount.vector2=sum(amount.inkg[source %in% c('Ink','Printer')]),
    amount.vector3=sum(amount.inkg[source %in% c('Recycling','Combusted')])
)


# OPTION 2. sum with logical indexing on the df:
# (This is from before you modified the question to one-row-per-company-and-per-year)
df$amount.vector1 <- sum( df[(df$source %in% c('Tea','Coffee')),]$amount.inkg )
# josilber clarifies you want one-row-per-company
...

选项 3。您也可以使用aggregate(manpage here) with subset(...),尽管总和的聚合是多余的。

aggregate(df, source %in% c('Tea','Coffee'), FUN = sum)

聚合的by参数是操作所在的位置(按标准选择、子集)。

注意:%in%执行扫描操作,因此如果您的向量和 df 变大,或者为了可扩展性,您需要将其分解为可以向量化的布尔操作: (source=='Tea' | source=='Coffee')

至于如果子集为空,则防止 NA 总和,sum(c()) = 0所以不用担心。但如果你这样做,要么使用 na.omit,要么ifelse(is.na(x),0,x)对最终结果执行。

于 2014-03-10T02:54:28.057 回答
1

对于拆分-应用-组合范式来说,这是一项很好的任务。首先,您按公司/年份对拆分数据框:

data = data.frame(company.raw = c("C1", "C1", "C2", "C2", "C2", "C2"),
                  years.raw = c(1, 1, 1, 1, 2, 2),
                  source = c("Ink", "Recycling", "Coffee", "Combusted", "Printer", "Tea"),
                  amount.inkg = c(5, 2, 10, 15, 14, 18))
spl = split(data, paste(data$company.raw, data$years.raw))

现在,您计算拆分数据中每个元素的汇总数据框:

spl2 = lapply(spl, function(x) {
  data.frame(Company=x$company.raw[1],
             Year=x$years.raw[1],
             amount.vector1 = sum(x$amount.inkg[x$source %in% vector1]),
             amount.vector2 = sum(x$amount.inkg[x$source %in% vector2]),
             amount.vector3 = sum(x$amount.inkg[x$source %in% vector3]))
})

最后,将所有内容组合在一起:

do.call(rbind, spl2)
#      Company Year amount.vector1 amount.vector2 amount.vector3
# C1 1      C1    1              0              5              2
# C2 1      C2    1             10              0             15
# C2 2      C2    2             18             14              0
于 2014-03-10T03:20:04.547 回答