在R中计算数据框中各列的平均值

4
我希望在R中对包含整数值和偶尔NA的数据框中的列求平均值。
数据框名为CD6(气候区划 6),其初始化为NA值,以存储属于气候分区6的所有数据的平均值。行代表日期,列表示从0到23的小时。数据框如下所示:
    > CD6

       Date       H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 ... H23
       1948-07-01 NA NA NA NA NA NA NA NA NA NA NA  ... NA
       1948-07-02 NA NA NA NA NA NA NA NA NA NA NA  ... NA
       1948-07-03 NA NA NA NA NA NA NA NA NA NA NA  ... NA

名为CA的数据框包含了所有气候分区(从1到7)的真实值。数据框大致如下:

    > CA

       Climate_Division  Date       H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 ... H23
       6                 1948-07-01 NA NA NA NA NA NA NA NA NA NA NA  ... NA
       5                 1948-07-01 0  1  1  3  0  0  0  0  0  0  0   ... 2
       6                 1948-07-01 0  1  1  3  0  0  0  0  0  0  0   ... 2
       6                 1948-07-01 1  0  0  5  7  0  1  1  1  0  0   ... 0
       6                 1948-07-02 0  2  1  2  1  1  NA 0  1  0  1  ... 2
       6                 1948-07-03 NA NA NA NA NA NA NA NA NA NA NA  ... NA

我编写了一个for循环,将迭代遍历CA数据帧中的每一行,并映射到正确的气候分区(在此示例中为CD6,指气候分区6)。问题是我不知道有多少行属于每个气候分区,以便正确计算平均值。
只看CD6,我想获取特定小时每个日期的平均值,如果存在真实值,则忽略NA,并且最终答案是整数(该值的上限)。如果各个气候分区所有小时的值都为NA, 我想保持它不变,而不是为0。CD6的最终结果应如下所示:
    > CD6

       Date       H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 ... H23
       1948-07-01 1  1  1  4  4  0  1  1  1  0  0   ... 1
       1948-07-02 0  2  1  2  1  1  NA 0  1  0  1  ... 2
       1948-07-03 NA NA NA NA NA NA NA NA NA NA NA  ... NA

我不太清楚如何编写代码并使其高效。因此,任何建议都将是有帮助的,感谢您的时间。


你能否将 dput(CA) 的输出粘贴在这里,以便我们可以重现你的数据? - CHP
当 Climate_Division = 6 且 Date = 1948-07-01 时,1 和 0 的平均值为1吗?难道不应该是0.5吗? - CHP
geektrader - 您是正确的,应该是0.5,但是我将其取整为1,以保持整数。 - Luciano Rodriguez
2个回答

2
你要做的是按照两个列 CAClimate_DivisionDate 进行分组的聚合操作。你可以使用内置的 aggregate 函数来实现。
> t <- 'Climate_Division  Date       H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10
+ 6                 1948-07-01 NA NA NA NA NA NA NA NA NA NA NA
+ 5                 1948-07-01 0  1  1  3  0  0  0  0  0  0  0 
+ 6                 1948-07-01 0  1  1  3  0  0  0  0  0  0  0 
+ 6                 1948-07-01 1  0  0  5  7  0  1  1  1  0  0 
+ 6                 1948-07-02 0  2  1  2  1  1  NA 0  1  0  1 
+ 6                 1948-07-03 NA NA NA NA NA NA NA NA NA NA NA'
> 
> CA <- read.table(textConnection(t), header=T)
> 
> CA
  Climate_Division       Date H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10
1                6 1948-07-01 NA NA NA NA NA NA NA NA NA NA  NA
2                5 1948-07-01  0  1  1  3  0  0  0  0  0  0   0
3                6 1948-07-01  0  1  1  3  0  0  0  0  0  0   0
4                6 1948-07-01  1  0  0  5  7  0  1  1  1  0   0
5                6 1948-07-02  0  2  1  2  1  1 NA  0  1  0   1
6                6 1948-07-03 NA NA NA NA NA NA NA NA NA NA  NA
> #Now that we have our data, we do aggregation of data and calculate mean over that using following command
> CAMeans <- aggregate(CA[,3:13], by =list(CA[,1], CA[,2]), FUN = mean, na.rm = TRUE)
> 
> CAMeans
  Group.1    Group.2  H0  H1  H2  H3  H4  H5  H6  H7  H8  H9 H10
1       5 1948-07-01 0.0 1.0 1.0   3 0.0   0 0.0 0.0 0.0   0   0
2       6 1948-07-01 0.5 0.5 0.5   4 3.5   0 0.5 0.5 0.5   0   0
3       6 1948-07-02 0.0 2.0 1.0   2 1.0   1 NaN 0.0 1.0   0   1
4       6 1948-07-03 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
> 
> #Need to change the names of grouping column back to what they were before
> names(CAMeans)[1:2] <- c('Climate_Division', 'Date')
> 
> CAMeans
  Climate_Division       Date  H0  H1  H2  H3  H4  H5  H6  H7  H8  H9 H10
1                5 1948-07-01 0.0 1.0 1.0   3 0.0   0 0.0 0.0 0.0   0   0
2                6 1948-07-01 0.5 0.5 0.5   4 3.5   0 0.5 0.5 0.5   0   0
3                6 1948-07-02 0.0 2.0 1.0   2 1.0   1 NaN 0.0 1.0   0   1
4                6 1948-07-03 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
> 
> #Now you can subset CAMeans to get content for CD6
> CD6 <- CAMeans[CAMeans$Climate_Division == 6, 2:ncol(CAMeans)]
> 
> CD6
        Date  H0  H1  H2  H3  H4  H5  H6  H7  H8  H9 H10
2 1948-07-01 0.5 0.5 0.5   4 3.5   0 0.5 0.5 0.5   0   0
3 1948-07-02 0.0 2.0 1.0   2 1.0   1 NaN 0.0 1.0   0   1
4 1948-07-03 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

1
我感到谦卑。不过,为自己辩护的话,问题有点晦涩。 - N8TRO
geektrader - 感谢您的帮助。我没有意识到函数aggregate可以很好地为我完成这个任务。Nathan - 对于造成的困惑,我感到抱歉。我尽力解释了一种复杂的绕路方法,但显然做得不够好。无论如何,还是非常感谢您的帮助。 - Luciano Rodriguez

1

我猜测你想要的是这两个选项之一:rowMeans()colMeans()。它们与编程有关。

CA <- read.table(
header=TRUE, text='Climate_Division  Date H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10  H23
6   1948-07-01 NA NA NA NA NA NA NA NA NA NA NA NA
5   1948-07-01 0  1  1  3  0  0  0  0  0  0  0 2
6   1948-07-01 0  1  1  3  0  0  0  0  0  0  0 2
6   1948-07-01 1  0  0  5  7  0  1  1  1  0  0 0
6   1948-07-02 0  2  1  2  1  1  NA 0  1  0  1 2
6   1948-07-03 NA NA NA NA NA NA NA NA NA NA NA NA')

CD6 <- data[CA$Climate_Division==6, ]   # Populating your data does not require a loop.

(CD6rmeans <- rowMeans(CD6[, -2], na.rm=TRUE))

#     1     3     4     5     6 
# 6.000 1.000 1.692 1.417 6.000 
t(CD6cmeans <- colMeans(CD6[ ,-2], na.rm=TRUE))

# Climate_Division     H0 H1     H2    H3    H4     H5  H6     H7     H8 H9    H10   H23
# [1,]           6 0.3333  1 0.6667 3.333 2.667 0.3333 0.5 0.3333 0.6667  0 0.3333 1.333

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接