计算数据框中条件变化的行差异

时间:2014-03-17 03:17:08

标签: r dataframe conditional-statements

Gidday, 我有一个数据框,如下所示:

> test[1:20,]
                companycode     year    expenses         reductions_to_year1
    1                 C1          1     8.47720                 NA
    2                 C1          2     8.45250                 NA
    3                 C1          3     8.46280                 NA
    4                 C2          1 14828.90603                 NA
    5                 C3          1   665.21565                 NA
    6                 C3          2   290.66596                 NA
    7                 C3          3   865.56265                 NA
    8                 C3          4   6785.03586                NA
    9                 C3          5   312.02617                 NA
    10                C3          6   760.48740                 NA
    11                C3          7  1155.76758                 NA
    12                C4          1  4565.78313                 NA
    13                C4          2  3340.36540                 NA
    14                C4          3  2656.73030                 NA
    15                C4          4  1079.46098                 NA
    16                C5          1    60.57039                 NA
    17                C6          1  6282.48118                 NA
    18                C6          2  7419.32720                 NA
    19                C7          1   644.90571                 NA
    20                C8          1 58332.34945                 NA

简短说明: 公司代码中的C1-C8是8家不同的公司。 $ year中的值显示数据($ expenses)存在的年份。费用以$ expenses显示。

我想要做的是计算每个公司的费用与每个公司的第1年的价值相比的年度差异(百分比)。计算值应显示在$ reductions_to_year1。

e.g。第1-3行

             companycode     year    expenses         reductions_to_year1
 1                 C1          1     8.47720                 0.0000000
 2                 C1          2     8.45250                 0.2913698
 3                 C1          3     8.46280                 0.1698674

我按如下方式计算值(%):

test[1,4]= 1-(test[1,3]/test[1,3]) # year 1, no difference
test[2,4]= 1-(test[2,3]/test[1,3]) # 0.2913698% difference to year 1 
test[3,4]= 1-(test[3,3]/test[1,3]) # 0.1698674% difference to year 1

挑战(对我而言)是这是一个包含大约1000行的数据框,大约300个不同的公司(显示为“C1”到“C300”的序列)和几年的数据(大约1-10) )。 我试图写一个循环,但是为了计算差异,每个公司必须使用第1年的价值这个方面很困难。

澄清一下,当$ companycode中的新公司出现时,需要将接下来几年的费用与第1年的费用进行比较。

我知道循环数据帧是低效的,这就是为什么我认为函数tapply,apply,sapply等可能是一个很好的方法......如果有人热衷于这样做会很棒。

我希望很清楚,你们可以帮助我。

提前致谢。

2 个答案:

答案 0 :(得分:1)

在基础R中,这是使用ave完成的。我包含了第一行,以防你所拥有的data.frame尚未按年份排序。如果是,那么你可以跳过它,因为ave中的函数依赖于data.frame已经排序,至少就像你在这里一样。

dat <- dat[order(dat$year),] # or order(s$companycode, s$year) to make it like presented here
dat$reductions_to_year1 <- 
   ave(dat$expenses, dat$company, FUN = function(x) 100*(1 - x/x[1]))

但是如果你用第一年的费用制作了一个矢量,它的工作速度会更快。

exp1 <-  ave( dat$expenses, dat$company, FUN = '[', '1' )

然后你可以依靠好的旧矢量化。

dat$reductions_to_year1 <- 100*(1 - dat$expenses/exp1)

答案 1 :(得分:0)

您可以非常简单地使用plyr包进行此类任务。正如评论中所指出的,这取决于按年份排序的data.frame:

library(plyr)
dat <- dat[order(dat$year),]
dat.out <- ddply(dat, .(companycode), transform, 
                 reductions_to_year1 = 100*(1 - (expenses/expenses[1])))

这会根据companycode将数据分成多个部分,然后对每个部分执行操作。我不确定我在计算中是否匹配您想要的内容,但您可以对每件作品进行任何计算。