将 data.frame 折叠为 data.frame——by() 和aggregate() 的问题

Bri*_*n B 5 r

考虑到我有以下数据和函数返回我喜欢的汇总统计信息

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
}
Run Code Online (Sandbox Code Playgroud)

我可以像这样成功地将该函数应用于数据子集:

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

或按国家/地区细分如下:

> 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 
Run Code Online (Sandbox Code Playgroud)

问题是,这不是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
Run Code Online (Sandbox Code Playgroud)

“没问题!” 我认为,因为类似的aggregate()函数确实返回 a 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
Run Code Online (Sandbox Code Playgroud)

问题是,它不能与任意函数一起正常工作:

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

我真正想要的是一个data.frame具有以下列的对象:

  • 国家
  • 系数
  • 软件开发
  • 最小百分比

我怎样才能做到这一点?

Jus*_*tin 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
Run Code Online (Sandbox Code Playgroud)

理想情况下,您的函数显式返回 a data.frame,但在这种情况下,它可以轻松且正确地强制为 1。