【问题标题】:Calculate means of rows计算行的平均值
【发布时间】:2011-05-17 00:12:34
【问题描述】:

我有一个名为 ants 的数据框,详细说明每个站点的多个条目,如下所示:

  Site     Date     Time  Temp SpCond Salinity Depth Turbidity Chlorophyll
1   71 6/8/2010 14:50:35 14.32  49.88    32.66 0.397       0.0         1.3
2   71 6/8/2010 14:51:00 14.31  49.94    32.70 1.073       0.0         2.0
3   71 6/8/2010 14:51:16 14.32  49.95    32.71 1.034      -0.1         1.6
4   71 6/8/2010 14:51:29 14.31  49.96    32.71 1.030      -0.2         1.6
5   70 6/8/2010 14:53:55 14.30  50.04    32.77 1.002      -0.2         1.2
6   70 6/8/2010 14:54:09 14.30  50.03    32.77 0.993      -0.5         1.2

网站有不同数量的条目,通常为 3,但有时更少或更多。如果日期和站点编号都匹配,我想编写一个新的数据框,每个站点有一个条目,详细说明每个参数的平均/平均读数。我希望从计算和后续数据框中省略空或“na”单元格。

我不确定这是一个应用函数还是 rowMeans 的一个版本?非常卡住,非常感谢任何帮助!

【问题讨论】:

    标签: r row average dataframe mean


    【解决方案1】:

    Nico 的答案看起来像我的答案,只是我会添加一个命名参数以传递给 mean() 以便 NA(在聚合列中)不会破坏结果。 (我不知道 OP 是否在询问 by 变量或 otehr 变量中的 NA 是否已知或怀疑有 NA):

    aggregate(df, by=list(df$Site, df$Date), FUN=mean, na.rm=TRUE)
    

    您可能还需要并行运行聚合或 tapply 调用来计算非 NA 值的数量。

    使用聚合的公式方法的其他方法可能会有所不同,因为 na.action=na.omit 是默认值:

    aggregate( . ~Site +Date, data=df,  FUN=mean, na.rm=TRUE)
    

    【讨论】:

      【解决方案2】:

      这是使用plyr 包及其ddply() 函数的一种方式:

      R> df
        Site     Date     Time  Temp SpCond Salinity Depth Turbidity Chlorophyll
      1   71 6/8/2010 14:50:35 14.32  49.88    32.66 0.397       0.0         1.3
      2   71 6/8/2010 14:51:00 14.31  49.94    32.70 1.073       0.0         2.0
      3   71 6/8/2010 14:51:16 14.32  49.95    32.71 1.034      -0.1         1.6
      4   71 6/8/2010 14:51:29 14.31  49.96    32.71 1.030      -0.2         1.6
      5   70 6/8/2010 14:53:55 14.30  50.04    32.77 1.002      -0.2         1.2
      6   70 6/8/2010 14:54:09 14.30  50.03    32.77 0.993      -0.5         1.2
      R> library(plyr)
      R> ddply(df, .(Site,Date), function(x) mean(x[,-(1:3)], na.rm=TRUE))
        Site     Date   Temp SpCond Salinity  Depth Turbidity Chlorophyll
      1   70 6/8/2010 14.300 50.035   32.770 0.9975    -0.350       1.200
      2   71 6/8/2010 14.315 49.933   32.695 0.8835    -0.075       1.625
      R> 
      

      我使用自定义匿名函数跳过前三列。

      【讨论】:

      • Dirk,您需要在 mean 呼叫中使用 na.rm = TRUE
      • 谢谢 Dirk,除了输出中缺少“时间”列之外,这很好用,所以我将其修改为:ddply(df, .(Site,Date), function(x) mean(x[, -(1:2)], na.rm=TRUE)) 但这会为“时间”下的值返回 NA,是否也可以平均时间?
      • @Joey 平均时间会给你什么价值?该数据与每日平均值有关。
      • 我认为您首先需要将日期+时间组合成(解析的)POSIXct 类型。超过这个你可以平均。你不能平均你现在在时间中拥有的东西,因为它是文本。这就是我跳过它的原因。
      • 我明白了……那我试试。我以为它会回到 Posixct,以前没有使用过,但应该试一试。谢谢你:)
      【解决方案3】:

      你也可以使用aggregate

      aggregate(df, by=list(df$Site, df$Date), FUN=mean, na.rm=TRUE)
      

      【讨论】:

      • 同上我对 Dirk 的评论。您需要在FUN = mean 之后添加, na.rm = TRUE 以排除NA 值。
      【解决方案4】:

      这是一个完整的新答案,其中包含完整的日志,还涵盖了您的新规范:

      R> Lines <- "  Site     Date     Time  Temp SpCond Salinity Depth Turbidity Chlorophyll
      + 71 6/8/2010 14:50:35 14.32  49.88    32.66 0.397       0.0         1.3
      + 71 6/8/2010 14:51:00 14.31  49.94    32.70 1.073       0.0         2.0
      + 71 6/8/2010 14:51:16 14.32  49.95    32.71 1.034      -0.1         1.6
      + 71 6/8/2010 14:51:29 14.31  49.96    32.71 1.030      -0.2         1.6
      + 70 6/8/2010 14:53:55 14.30  50.04    32.77 1.002      -0.2         1.2
      + 70 6/8/2010 14:54:09 14.30  50.03    32.77 0.993      -0.5         1.2
      + "
      R> con <- textConnection(Lines)
      R> df <- read.table(con, sep="", header=TRUE, stringsAsFactors=FALSE)
      R> close(con)
      R> df$pt <- as.POSIXct(strptime(paste(df$Date, df$Time), "%m/%d/%Y %H:%M:%S"))
      R> library(plyr)
      R> newdf <- ddply(df, .(Site,Date), function(x) mean(x[,-(1:3)], na.rm=TRUE))
      R> newdf$pt <- as.POSIXct(newdf$pt, origin="1970-01-01")
      R> newdf
        Site     Date  Temp SpCond Salinity  Depth Turbidity Chlorophyll                  pt
      1   70 6/8/2010 14.30  50.03    32.77 0.9975    -0.350       1.200 2010-06-08 20:54:02
      2   71 6/8/2010 14.32  49.93    32.70 0.8835    -0.075       1.625 2010-06-08 20:51:05
      R> 
      

      【讨论】:

      • 你太棒了,对不起,我完全被卡住了!这太好了,现在对我来说更有意义了……谢谢!而且,是的,现在结束了:)
      • 你无法想象我有多少次把自己的头撞在墙上 a) 因素/角色的事情,b) 在 strptime 和 c) 那个该死的 origin= 之后忘记 as.POSIXct重铸为as.POSIXct。但幸运的是,我已经坚持了足够长的时间,最终它卡住了:)
      • 顺便说一句,这是完全可复制的示例在问题中更有用的原因之一。所以不要只显示print(df),显示生成或使用dput(df) 的代码,它会在ascii 中紧凑地序列化它以供娱乐。
      【解决方案5】:

      您与rowMeans() 关系密切,但您需要colMeans()。其他人已经展示了如何使用内置或附加功能,我当然会推荐你使用它们。但是,了解如何手动执行此类操作可能会很有用:

      ## using df from Dirk's answer, we split the data in Site Date combinations
      df.sp <- with(df,
                    split(data.frame(Temp, SpCond, Salinity, Depth, Turbidity,
                                     Chlorophyll),
                          list(Site = Site, Date = Date)))
      ## The above gives  a list of data frames one per date-site combo,
      ## to which we apply the colMeans() function
      df.mean <- data.frame(t(sapply(df.sp, colMeans)))
      

      此时,如果您希望输出与其他人的答案一样好,我们需要做一些额外的整理:

      ## Process the rownames on df.mean
      name.parts <- strsplit(rownames(df.mean), "\\.")
      ## pull out the Site part (before the '.')
      df.mean <- within(df.mean, Site <- as.numeric(sapply(name.parts, `[`, 1)))
      ## pull out the Date part (after the '.')
      df.mean <- within(df.mean, Date <- sapply(name.parts, `[`, 2))
      ## rearrange the columns
      df.mean <- df.mean[, c(7:8,1:6)]
      

      再次注意,在大多数情况下,您应该使用其他答案所述的罐装函数。然而,有时编写自己的解决方案可能会更快,以上内容可以作为实现此目标的指南。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-03
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        • 2013-01-14
        • 2017-02-06
        • 2012-06-19
        相关资源
        最近更新 更多