比较组均值

时间:2019-02-10 07:24:09

标签: r data.table mean

我有一个看起来如下的数据集:

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
)

2 个答案:

答案 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