2

次のようなデータフレームがあります。

    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))

すべての「サイト」について、「エネルギー」[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))

これは、パッケージ plyr の ddply とそのパッケージの numcolwise の組み合わせに最適です。しかし、どういうわけか私はそれを正しく理解することができません.問題は「エネルギー」コンポーネントを選択することです.

誰でもこれを解決する方法を知っていますか? [前もって感謝します...]

4

3 に答える 3

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)]

そして、これを使用してそれを行う方法は次の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")

そして、ここに使用する方法があります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]

マシューから編集:

それに基づいて、 join inherited scopeを使用して、少し高度な(そして高速な)data.table方法を構築します。

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]

ではなくi.からその変数を取得するように指示する接頭辞に注意してください。SQL テーブル名のプレフィックスに似ています。これにより、大きなステップが回避されます。FAQ 1.12 で説明されているテクニック。ixmerge

複数の:=イン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 } ]
于 2012-08-21T09:20:00.900 に答える
4

これはあなたの例で仕事をします:

library(plyr)
ddply(mat.in, .(site), transform, quote.2011 = year.2011/year.2011[var=="energy"],      
      quote.2012 = year.2012/year.2012[var=="energy"])

これをより一般的に行うには、最初meltにデータを年を列名ではなく値に変換します。

これがどのように機能するかですmelt

library(reshape2)
mat.m <- melt(mat.in, id.vars=1:2, variable.name="year")
mat.m$year <- sub("year.", "", mat.m$year)
mat.out <- ddply(mat.m, .(site, year), transform, quote = value/value[var=="energy"])
于 2012-08-21T08:57:50.010 に答える