如何仅获取特定行的列均值?

Posted

技术标签:

【中文标题】如何仅获取特定行的列均值?【英文标题】:How to get column mean for specific rows only? 【发布时间】:2012-09-05 20:05:01 【问题描述】:

我需要获取特定行(此处:年份)的一列(此处:分数)的平均值。具体来说,我想知道三个时段的平均分:

时期 1:年 周期 2:年 >= 1984 & 年 第 3 期:年 >= 1991

这是我的数据结构:

  country year     score        
 Algeria 1980     -1.1201501 
 Algeria 1981     -1.0526943 
 Algeria 1982     -1.0561565 
 Algeria 1983     -1.1274560 
 Algeria 1984     -1.1353926 
 Algeria 1985     -1.1734330 
 Algeria 1986     -1.1327666 
 Algeria 1987     -1.1263586 
 Algeria 1988     -0.8529455 
 Algeria 1989     -0.2930265 
 Algeria 1990     -0.1564207 
 Algeria 1991     -0.1526328 
 Algeria 1992     -0.9757842 
 Algeria 1993     -0.9714060 
 Algeria 1994     -1.1422258 
 Algeria 1995     -0.3675797 
 ...

计算的平均值应添加到附加列(“平均值”)中的 df,即第 1 年的年份相同,第 2 年的年份相同,以此类推。

它应该是这样的:

country year     score         mean   
 Algeria 1980     -1.1201501     -1.089
 Algeria 1981     -1.0526943     -1.089
 Algeria 1982     -1.0561565     -1.089
 Algeria 1983     -1.1274560     -1.089
 Algeria 1984     -1.1353926     -0.839
 Algeria 1985     -1.1734330     -0.839
 Algeria 1986     -1.1327666     -0.839
 Algeria 1987     -1.1263586     -0.839
 Algeria 1988     -0.8529455     -0.839
 Algeria 1989     -0.2930265     -0.839
 Algeria 1990     -0.1564207     -0.839
 ...

我尝试过的每条可能的路径都很容易变得超级复杂 - 我必须计算 90 多个国家/地区不同时间段的平均分数...

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:
datfrm$mean <-
  with (datfrm, ave( score, findInterval(year, c(-Inf, 1984, 1991, Inf)), FUN= mean) )

标题问题与真正的问题有点不同,将通过使用逻辑索引来回答。如果只想要特定子集的平均值,比如year &gt;= 1984 &amp; year &lt;= 1990,可以通过以下方式完成:

mn84_90 <- with(datfrm, mean(score[year >= 1984 & year <= 1990]) )

【讨论】:

哇!这非常快 - 确实非常有帮助。非常感谢这个超级优雅的解决方案! findInterval 功能需要更好的广告代理。【参考方案2】:

由于findInterval 需要对year 进行排序(如您的示例中所示),我很想使用cut 以防它未排序 [证明是错误的,谢谢@DWin]。为完整起见,data.table 等效项(适用于大数据)为:

require(data.table)
DT = as.data.table(DF)   # or just start with a data.table in the first place

DT[, mean:=mean(score), by=cut(year,c(-Inf,1984,1991,Inf))]

findInterval 使用 DWin 可能更快:

DT[, mean:=mean(score), by=findInterval(year,c(-Inf,1984,1991,Inf))]

【讨论】:

关于 findInterval 的说法不正确(经测试确认),但感谢 DT 提供。【参考方案3】:

如果这些行是按年份排序的,我认为最简单的方法是:

m80_83 <- mean(dataframe[1:4,3]) #Finds the mean of the values of column 3 for rows 1 through 4
m84_90 <- mean(dataframe[5:10,3])
#etc.

如果行不是按年份排序的,我会像这样使用 tapply。

list.of.means <- c(tapply(dataframe$score, cut(dataframe$year, c(0,1983.5, 1990.5, 3000)), mean)

这里,tapply 接受三个参数:

首先,您要处理的数据(在本例中为 datafram$score)。

其次,将数据分成组的函数。在这种情况下,它将根据 dataframe$year 值将数据分成三组。第 1 组将包括 dataframe$year 值从 0 到 1983.5 的所有行,第 2 组将包括 dataframe$year 值从 1983.5 到 1990.5 的所有行,第 3 组将包括 dataframe$year 值从 1983.5 到 3000 的所有行。

第三,应用于每个组的功能。此函数将应用于您选择作为第一个参数的数据。

因此,list.of.means 应该是您要查找的 3 个值的列表。

【讨论】:

以上是关于如何仅获取特定行的列均值?的主要内容,如果未能解决你的问题,请参考以下文章

如何从选定行的网格面板中仅获取特定值

仅计算“今天”之前的日期列的平均值

如何省略 SQL 中特定行的列?

如何在Python中按十年计算列的平均值

如何自动化文件路径以从多个 csv 文件的列中获取平均值?

如何获得 2 个不同 WHERE 子句的列的平均值?