我有一个看起来如下的数据集:
library(data.table)
df <- fread(
"A B C fac H I J iso year matchcode
0 1 1 NA 0 1 0 NLD 2009 NLD2009
1 0 2 NA 1 0 1 NLD 2009 NLD2009
0 0 3 B 1 0 0 AUS 2011 AUS2011
1 0 4 B 0 1 0 AUS 2011 AUS2011
0 1 7 NA 0 0 0 NLD 2008 NLD2008
1 0 1 A 0 1 0 NLD 2008 NLD2008
0 0 3 B 1 0 0 AUS 2012 AUS2012
1 0 4 B 0 1 0 AUS 2012 AUS2012",
header = TRUE
)
对于每个国家,我想检查C
的平均值是否随时间变化。所以我做到了:
setDT(df)[, c("MeanValue_C", "Residual_C") := {m= mean(C, na.rm=TRUE);list(m, C-m)}, by=list(iso, year)]
这从本质上给了我我想要的信息。但是没有任何有用的格式。我尝试做table(df$MeanValue_C, df$matchcode)
,但是这造成了很大的混乱,因为实际的数据集大约有100个国家(有2年或更长时间)。
在不创建其他数据表的情况下,比较每个国家/地区的分组均值的最简单方法是什么?
理想情况是:
df2 <- fread(
"C iso year matchcode
1.5 NLD 2009 NLD2009
3.5 AUS 2011 AUS2011
4 NLD 2008 NLD2008
3.5 AUS 2012 AUS2012",
header = TRUE
)
答案 0 :(得分:2)
这是一个开始。您可以对每个国家/地区的年平均值运行summary
,以获取每个国家/地区的一些基本样本矩。 summary
返回5位数摘要+均值的向量; as.list
对此进行转换,因此每个元素都是一列。 keyby
对分组进行排序(即在执行操作后运行setkey
)
df[ , .(c_mean = mean(C, na.rm = TRUE)), keyby = .(iso, year, matchcode)
][ , as.list(summary(c_mean)), keyby = .(iso, matchcode)]
# iso matchcode Min. 1st Qu. Median Mean 3rd Qu. Max.
# 1: AUS AUS2011 3.5 3.5 3.5 3.5 3.5 3.5
# 2: AUS AUS2012 3.5 3.5 3.5 3.5 3.5 3.5
# 3: NLD NLD2008 4.0 4.0 4.0 4.0 4.0 4.0
# 4: NLD NLD2009 1.5 1.5 1.5 1.5 1.5 1.5
不幸的是,summary
的输出类型不能保证像此处一样为length-5。特别是对于数字,如果输入中有任何NA_real_
值,则长度为6。由于您已经运行过na.rm = TRUE
,因此只有在存在iso
-matchcode
组合且没有非NA
值的情况下,这才有可能(要确认这一点,请运行summary(mean(NA_real_, na.rm = TRUE))
)。要继续,您可以例如将这些值预先放置:
df[ , keyby = .(iso, year, matchcode),
if (!all(is.na(C)) .(c_mean = mean(C, na.rm = TRUE)),
][ , as.list(summary(c_mean)), keyby = .(iso, matchcode)]
或在中间放下它们:
df[ , .(c_mean = mean(C, na.rm = TRUE)), keyby = .(iso, year, matchcode)
][!is.na(c_mean), as.list(summary(c_mean)), keyby = .(iso, matchcode)]
或者,如果您不想丢失该信息(某些组合丢失),则可以强制输出更加一致:
df[ , .(c_mean = mean(C, na.rm = TRUE)), keyby = .(iso, year, matchcode)
][ , {
s = summary(c_mean)
if (length(s) == 5L) s = c(s, `NA's` = 0L)
as.list(s)
}, keyby = .(iso, matchcode)]
(您可以通过运行summary.default
来检查print(summary.default)
的代码,以确保自己可以使用此代码)
答案 1 :(得分:1)
没有明确说解决方案需要为data.table
,但是要获得声明的输出的tidyverse
解决方案是:
library(tidyverse)
df %>%
group_by(iso, year, matchcode) %>%
summarise(C = mean(C)) %>%
select(C, iso, year, matchcode)
# A tibble: 4 x 4
# Groups: iso, year [4]
C iso year matchcode
<dbl> <chr> <int> <chr>
1 3.5 AUS 2011 AUS2011
2 3.5 AUS 2012 AUS2012
3 4 NLD 2008 NLD2008
4 1.5 NLD 2009 NLD2009