R plyr应用于行

Hen*_*enk 2 r plyr data.table

我有一个这样的数据框:

    mat.in=data.frame(site=c('A','A','A','B','B','B'),
    var=c('product.A','product.B','energy','product.A','product.B','energy'),
    year.2011=c(12,10,40,14,12,60),year.2012=c(13,11,45,25,13,65))
Run Code Online (Sandbox Code Playgroud)

对于每个'网站'我想要除以'能量'[numcol wise],所以我会得到:

    mat.out=data.frame(site=c('A','A','A','B','B','B'),
    var=c('product.A','product.B','energy','product.A','product.B','energy'),
    year.2011=c(12,10,40,14,12,60),year.2012=c(13,11,45,25,13,65),
    quot.2011=c(0.30,0.25,1.00,0.23,0.20,1.00),quot.2012=c(0.29,0.24,1.00,0.38,0.20,1.00))
Run Code Online (Sandbox Code Playgroud)

这将非常适合来自包plyr的ddply以及该包的numcolwise.但不知何故,我无法做到正确 - 问题是挑选出"能量"成分.

谁知道怎么解决这个问题?[提前致谢...]

ROL*_*OLO 5

来自@seancarmody的酷答案.

以下是使用基本函数执行此操作的另一种方法:

# Select and join frames
mat.out<-merge(mat.in[grep("product", mat.in$var),], mat2 <- mat.in[mat.in$var=="energy",], "site")
# Calculate the quot values
mat.out$quot.2011=mat.out$year.2011.x/mat.out$year.2011.y
mat.out$quot.2012=mat.out$year.2012.x/mat.out$year.2012.y

# And if needs be you can remove the energy columns
mat.out[,-c(5,6,7)]
Run Code Online (Sandbox Code Playgroud)

以下是使用以下方法的方法sqldf:

variable<-'p.site,p.var,p.year_2011,p.year_2012,
           p.year_2011/e.year_2011 AS quot_2011,
           p.year_2012/e.year_2012 AS quot_2012'
tables<- '(SELECT *
           FROM    `mat.in`
           WHERE   var LIKE \"product%\"
           )
           AS p,
           (SELECT *
           FROM    `mat.in`
           WHERE   var LIKE \"energy\"
           )
           AS e'

fn$sqldf("SELECT $variable FROM $tables WHERE  p.site=e.site")
Run Code Online (Sandbox Code Playgroud)

这是一种使用方式data.table:

dt <- data.table(mat.in, key="site")
# Join
mat.out <- dt[var %like% "product"][dt[var=="energy"]]
# Calculate
mat.out <- mat.out[,quot.2011:=year.2011/year.2011.1]
mat.out <- mat.out[,quot.2012:=year.2012/year.2012.1]
Run Code Online (Sandbox Code Playgroud)

马修编辑:

在此基础上data.table,使用join继承范围稍微更高级(和更快)的方式:

dt <- data.table(mat.in, key="site")
dt[dt[var=="energy"],quot.2011:=year.2011/i.year.2011]
dt[dt[var=="energy"],quot.2012:=year.2012/i.year.2012]
Run Code Online (Sandbox Code Playgroud)

注意i.前缀告诉它从而i不是获取变量x.与SQL表名前缀类似.这避免了merge大步; FAQ 1.12中描述的技术.

当实现多个:=in时j,它将成为:

dt <- data.table(mat.in, key="site")
dt[dt[var=="energy"], { quot.2011:=year.2011/i.year.2011
                        quot.2012:=year.2012/i.year.2012 } ]
Run Code Online (Sandbox Code Playgroud)