【问题标题】:summarize data from csv using R使用 R 汇总来自 csv 的数据
【发布时间】:2012-06-04 00:56:52
【问题描述】:

我是 R 新手,我根据需要编写了一些代码来汇总 .csv 文件中的数据。

这里是代码。

raw <- read.csv("trees.csv")

看起来像这样

                                 SNAME     CNAME        FAMILY PLOT INDIVIDUAL CAP   H
1 Alchornea triplinervia (Spreng.) M. Arg. Tainheiro Euphorbiaceae    5        176  15 9.5
2               Andira fraxinifolia Benth.   Angelim      Fabaceae    3        321  12 6.0
3               Andira fraxinifolia Benth.   Angelim      Fabaceae    3        326  14 7.0
4               Andira fraxinifolia Benth.   Angelim      Fabaceae    3        327  18 5.0
5               Andira fraxinifolia Benth.   Angelim      Fabaceae    3        328  12 6.0
6               Andira fraxinifolia Benth.   Angelim      Fabaceae    3        329  21 7.0

#add 2 other rows
for (i in 1:nrow(raw)) {
  raw$VOLUME[i] <- treeVolume(raw$CAP[i],raw$H[i])  
  raw$BASALAREA[i] <- treeBasalArea(raw$CAP[i])
}

#来了。 我需要一个新的数据框,其中包含 H 列和 CAP 列的平均值以及 VOLUME 和 BASALAREA 列的总和。此数据框按列 SNAME 分组,并按列 PLOT 分组。

plotSummary = merge(
  aggregate(raw$CAP ~ raw$SNAME * raw$PLOT, raw, mean),
  aggregate(raw$H ~ raw$SNAME * raw$PLOT, raw, mean))

plotSummary = merge(
  plotSummary,
  aggregate(raw$VOLUME ~ raw$SNAME * raw$PLOT, raw, sum))


plotSummary = merge(
  plotSummary,
  aggregate(raw$BASALAREA ~ raw$SNAME * raw$PLOT, raw, sum))

函数 treeVolume 和 treeBasal area 只返回数字。

treeVolume <- function(radius, height) {
  return (0.000074230*radius**1.707348*height**1.16873)
}

treeBasalArea <- function(radius) {
  return (((radius**2)*pi)/40000)
}

我确信有更好的方法可以做到这一点,但是如何呢?

【问题讨论】:

  • 用不那么重复的东西替换丑陋的 4 聚合
  • @user1424495 虽然很高兴看到您尝试了什么,所以我们知道要改进什么,如果您认为您的代码“丑陋”,那么也许您可以用文字告诉我们什么是做。评论#here comes 没有多大帮助。
  • 而且,为了使您的代码可重现,我们需要函数 treeVolumetreeBasalArea 或它们的调用结果。
  • 根据您的上次修订更新了我的答案。希望它比您当前的解决方案更直观

标签: r dataframe aggregate summary


【解决方案1】:

我无法读取您的示例数据,但我想我已经制作了一些通常代表它的东西......所以试一试。此答案基于 Greg 的建议,即查看 plyr 和函数 ddply 以按您的 data.frame 和 numcolwise 的段分组以计算您感兴趣的统计数据。

#Sample data
set.seed(1)
dat <- data.frame(sname = rep(letters[1:3],2), plot = rep(letters[1:3],2), 
                  CAP = rnorm(6), 
                  H = rlnorm(6), 
                  VOLUME = runif(6),
                  BASALAREA = rlnorm(6)
                  )


#Calculate mean for all numeric columns, grouping by sname and plot
library(plyr)
ddply(dat, c("sname", "plot"), numcolwise(mean))
#-----
  sname plot        CAP        H    VOLUME BASALAREA
1     a    a  0.4844135 1.182481 0.3248043  1.614668
2     b    b  0.2565755 3.313614 0.6279025  1.397490
3     c    c -0.8280485 1.627634 0.1768697  2.538273

编辑 - 对更新问题的回复

好的 - 现在您的问题或多或少可以重现,这就是我的处理方法。首先,您可以利用 R 是 vectorized 的事实,这意味着您可以一次计算 VOLUME 和 BASALAREA 中的所有值,而无需遍历每一行。对于这一点,我推荐transform 函数:

dat <- transform(dat, VOLUME = treeVolume(CAP, H), BASALAREA = treeBasalArea(CAP))

其次,意识到您打算计算 CAP 和 H 以及 VOLUME 和 BASALAREA 的不同统计数据,我建议使用 summarize 函数,如下所示:

ddply(dat, c("sname", "plot"), summarize,
  meanCAP = mean(CAP),
  meanH = mean(H),
  sumVOLUME = sum(VOLUME),
  sumBASAL = sum(BASALAREA)
  )

这将为您提供如下所示的输出:

  sname plot   meanCAP     meanH    sumVOLUME     sumBASAL
1     a    a 0.5868582 0.5032308 9.650184e-06 7.031954e-05
2     b    b 0.2869029 0.4333862 9.219770e-06 1.407055e-05
3     c    c 0.7356215 0.4028354 2.482775e-05 8.916350e-05

?ddply, ?transform, ?summarize 的帮助页面应该很有洞察力。

【讨论】:

    【解决方案2】:

    查看plyr 包。我将按 SNAME 变量为您拆分数据,然后您为其提供代码以执行您想要的一组汇总(混合均值和总和等),然后它将为您重新组合在一起。您可能需要该包中的“ddply”或“daply”函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多