我有一些关于植物生长的月度数据。每个对象都是一个固定的列数,行数等于植物存活的月份数。我想取这些物体的平均值,以便平均值只考虑在给定的时间步调下生存下来的植物。下面是示例数据:
df1 <- data.frame(GPP = 1:10, NPP = 1:10)
df2 <- data.frame(GPP = 2:8, NPP = 2:8)
df3 <- data.frame(GPP = 3:9, NPP = 3:9 )
在这种情况下,最大的时间步骤是10,第二和第三种植物没有存活这么长时间。换句话说,我最初的想法是用NA
替换空空间,使维度保持不变,如下所示:
na <- matrix( , nrow = 3, ncol = 2)
colnames(na) <- c("GPP","NPP")
df2 <- rbind(df2, na)
df3 <- rbind(df3, na)
这是不可取的,因为NA
并不像我所希望的那样简单地忽略值,而是使字段无效,导致所有算术输出成为NA
,如下所示:
(df1 + df2 + df3) / 3
GPP NPP
1 2 2
2 3 3
3 4 4
4 5 5
5 6 6
6 7 7
7 8 8
8 NA NA
9 NA NA
10 NA NA
我不能仅仅用0来填充na
,因为我想看到每一株植物在给定的时间步调下生存的平均值,同时完全忽略那些已经死亡的植物。用0代替会扭曲平均值,而不是达到这一目的。对于这里的示例数据,这是所需的结果
(df1 + df2 + df3) / 3
GPP NPP
1 2 2
2 3 3
3 4 4
4 5 5
5 6 6
6 7 7
7 8 8
8 8 8
9 9 9
10 10 10
这里,第8-10行被来自df1
的值替换,因为df2
和df3
中只有7行。
发布于 2021-05-25 17:22:00
我要重申我的评论:在做任何其他事情之前,在原始数据中对月份进行编码通常要安全得多;它是显式的,并将使您免受管道后面可能无意中更改行顺序的错误(这完全破坏了您希望达到的任何有效意义)。此外,由于我将建议将所有数据放在一个帧中,让我们也对工厂编号进行编码(即使我们不立即使用它)。
为此,那么:
df1 <- data.frame(plant = "A", month = 1:10, GPP = 1:10, NPP = 1:10)
df2 <- data.frame(plant = "B", month = 1:7, GPP = 2:8, NPP = 2:8)
df3 <- data.frame(plant = "C", month = 1:7, GPP = 3:9, NPP = 3:9)
因此,我非常喜欢把所有的数据都放在一个帧中。https://stackoverflow.com/a/24376207/3358227非常了解这一点,其中的一个前提是,如果您要对一组帧执行相同的操作,那么它应该是一个帧列表或一个组合帧(保留源id编码):
dfs <- do.call(rbind, list(df1, df2, df3))
### just a sampling, for depiction
dfs[c(1:2, 10:12, 17:19),]
# plant month GPP NPP
# 1 A 1 1 1
# 2 A 2 2 2
# 10 A 10 10 10
# 11 B 1 2 2
# 12 B 2 3 3
# 17 B 7 8 8
# 18 C 1 3 3
# 19 C 2 4 4
基R
aggregate(cbind(GPP, NPP) ~ month, data = dfs, FUN = mean, na.rm = TRUE)
# month GPP NPP
# 1 1 2 2
# 2 2 3 3
# 3 3 4 4
# 4 4 5 5
# 5 5 6 6
# 6 6 7 7
# 7 7 8 8
# 8 8 8 8
# 9 9 9 9
# 10 10 10 10
德普利
library(dplyr)
dfs %>%
group_by(month) %>%
summarize(across(c(GPP, NPP), mean))
# # A tibble: 10 x 3
# month GPP NPP
# <int> <dbl> <dbl>
# 1 1 2 2
# 2 2 3 3
# 3 3 4 4
# 4 4 5 5
# 5 5 6 6
# 6 6 7 7
# 7 7 8 8
# 8 8 8 8
# 9 9 9 9
# 10 10 10 10
侧重点:在本摘要中,您“丢失”的两位数据是数据的大小和每个月的可变性。您可以将它们包括在以下内容中:
dfs %>%
group_by(month) %>%
summarize(across(c(GPP, NPP), list(mu = ~ mean(.), sigma = ~ sd(.), len = ~ length(.))))
# # A tibble: 10 x 7
# month GPP_mu GPP_sigma GPP_len NPP_mu NPP_sigma NPP_len
# <int> <dbl> <dbl> <int> <dbl> <dbl> <int>
# 1 1 2 1 3 2 1 3
# 2 2 3 1 3 3 1 3
# 3 3 4 1 3 4 1 3
# 4 4 5 1 3 5 1 3
# 5 5 6 1 3 6 1 3
# 6 6 7 1 3 7 1 3
# 7 7 8 1 3 8 1 3
# 8 8 8 NA 1 8 NA 1
# 9 9 9 NA 1 9 NA 1
# 10 10 10 NA 1 10 NA 1
在这种情况下,8
的平均值可能是有意义的,但是注意到它是一个len
gth值1也是该统计数据的“强度”的信息(即弱的)。
发布于 2021-05-25 17:11:38
library(dplyr)
df1 <- data.frame(month = 1:10, GPP = 1:10, NPP = 1:10)
df2 <- data.frame(month = 1:7, GPP = 2:8, NPP = 2:8)
df3 <- data.frame(month = 1:7, GPP = 3:9, NPP = 3:9 )
df <- rbind(df1, df2, df3)
df %>%
group_by(month) %>%
summarise(GPP = mean(GPP),
NPP = mean(NPP))
month GPP NPP
<int> <dbl> <dbl>
1 1 2 2
2 2 3 3
3 3 4 4
4 4 5 5
5 5 6 6
6 6 7 7
7 7 8 8
8 8 8 8
9 9 9 9
10 10 10 10
发布于 2021-05-25 17:26:01
使用data.table
library(data.table)
rbindlist(mget(ls(pattern = '^df\\d+$')))[, lapply(.SD, mean), month]
https://stackoverflow.com/questions/67692476
复制相似问题