5

私が好きな要約統計を返す次のデータと関数があるとします。

landlines <- data.frame(
                year=rep(c(1990,1995,2000,2005,2010),times=3),
                country=rep(c("US", "Brazil", "Asia"), each=5),
                pct =  c(0.99, 0.99, 0.98, 0.05, 0.9,
                         0.4,  0.5,  0.55, 0.5,  0.45,
                         0.7,  0.85, 0.9,  0.85, 0.75)
                )
someStats <- function(x)
{
  dp <- as.matrix(x$pct)-mean(x$pct)
  indp <- as.matrix(x$year)-mean(x$year)
  f <- lm.fit( indp,dp )$coefficients
  w <- sd(x$pct)
  m <- min(x$pct)
  results <- c(f,w,m)
  names(results) <- c("coef","sdev", "minPct")
  results
}

次のように、その関数をデータサブセットに正常に適用できます。

> someStats(landlines[landlines$country=="US",])
      coef      sdev    minPct 
 -0.022400  0.410938  0.050000 

または、次のような国別の内訳を見てください。

> by(landlines, list(country=landlines$country), someStats)
country: Asia
      coef       sdev     minPct 
0.00200000 0.08215838 0.70000000 
--------------------------------------------------------------------------------------- 
country: Brazil
      coef       sdev     minPct 
0.00200000 0.05700877 0.40000000 
--------------------------------------------------------------------------------------- 
country: US
     coef      sdev    miPct 
-0.022400  0.410938  0.050000 

問題は、それはdata.frame私がさらに処理するために必要なオブジェクトではなく、そのようにキャストされないことです:

> as.data.frame( by(landlines, list(country=landlines$country), someStats) )
Error in as.data.frame.default(by(landlines, list(country = landlines$country),  : 
  cannot coerce class '"by"' into a data.frame

"問題ない!" aggregate()同様の関数が返すので、私は思うdata.frame

> aggregate(landlines$pct, by=list(country=landlines$country), min)
  country    x
1    Asia 0.70
2  Brazil 0.40
3      US 0.05

問題は、任意の関数では正しく動作しないことです:

> aggregate(landlines, by=list(country=landlines$country), someStats)
Error in x$pct : $ operator is invalid for atomic vectors

私が本当に取得したいのはdata.frame、次の列を持つオブジェクトです。

  • 係数
  • sdev
  • 最小パーセント

どうやってやるの?

4

3 に答える 3

4

パッケージを見てplyr、特にddply

> ddply(landlines, .(country), someStats)
  country    coef       sdev minPct
1    Asia  0.0020 0.08215838   0.70
2  Brazil  0.0020 0.05700877   0.40
3      US -0.0224 0.41093795   0.05

関数が明示的に a を返すのdata.frameが理想的ですが、この場合、簡単かつ正確に a に強制することができます。

于 2012-04-04T14:58:53.333 に答える
4

byrbindオブジェクトは実際にはリストであるため、次のように使用できますdo.call

do.call("rbind",by(landlines, list(country=landlines$country), someStats))
          coef       sdev minPct
Asia    0.0020 0.08215838   0.70
Brazil  0.0020 0.05700877   0.40
US     -0.0224 0.41093795   0.05
于 2012-04-04T15:27:53.707 に答える
3

aggregate別の目的のために設計されています。あなたが欲しいのはlapply(split())

> lapply( split(landlines, list(country=landlines$country)), FUN=someStats)
$Asia
      coef       sdev     minPct 
0.00200000 0.08215838 0.70000000 

$Brazil
      coef       sdev     minPct 
0.00200000 0.05700877 0.40000000 

$US
     coef      sdev    minPct 
-0.022400  0.410938  0.050000 

出力が予想どおり規則的である場合は、sapply を使用する方がよい場合があります。

> sapply( split(landlines, list(country=landlines$country)), FUN=someStats)
             Asia     Brazil        US
coef   0.00200000 0.00200000 -0.022400
sdev   0.08215838 0.05700877  0.410938
minPct 0.70000000 0.40000000  0.050000

行名に値を含む最初の列を作成するデモを追加しました:

> ttbl <- as.data.frame(t(tbl))
> ttbl <- cbind(Country=rownames(ttbl), ttbl)
> ttbl
       Country    coef       sdev minPct
Asia      Asia  0.0020 0.08215838   0.70
Brazil  Brazil  0.0020 0.05700877   0.40
US          US -0.0224 0.41093795   0.05
于 2012-04-04T15:11:44.340 に答える