R:运行 使用 dplyr 按组对前几年进行 t 检验
R: Run t-test on previous years by group using dplyr
我有一个包含不同组、年份及其值的数据框,例如:
data <- data.frame(
group = c(rep('A', 120), rep('B', 120)),
year = rep(c(rep('2013-2014', 40), rep('2014-2015', 40), rep('2015-2016', 40)), 2),
value = rnorm(240)
)
对于每个组中的每一年,我想 运行 进行 t 检验以查看这些值是否与前几年有显着差异(我一直在使用函数 t.test(x, y, var.equal = TRUE) 一次性执行此操作)
我想 return 数据框和 p 值,或者最好是使用 gtools::stars.pval() 生成的重要星星。所以 return 类似下面的内容
group year significance
A 2013-2014 NA
A 2014-2015 **
A 2015-2016 ***
B 2013-2014 NA
B 2014-2015
B 2015-2016
其中,2014-2015 和 2013-2014 之间差异的 p 值对于 'A' 在 0.001 和 0.01 之间,而 2015-2015 和 2014-2015 之间差异的 p 值对于 A <0.001。没有证据表明 B.
在任何年份有任何显着差异
不能保证每个组的年数都相同。
最好最快的方法是什么?我希望我可以按组和年份使用 dplyr 和 group_by 来做到这一点?
另一种选择是汇总数据框,将一个单元格中的所有值存储为列表(是的,您可以这样做 - 数据框可以在其中嵌套列表!)
使用 dplyr:
df=tbl_df(data)
df=arrange(df,group,year) %>% group_by(group,year) %>% summarise(values=list(value))
df=mutate(df,prev_values=lag(values))
df=group_by(df,group,year)
df=filter(df,!any(is.na(unlist(prev_values))))
df=mutate(df,p_value=t.test(unlist(values),unlist(prev_values),var.equal=TRUE)$p.value) %>% print
group year values prev_values p_value
1 A 2014-2015 <dbl[40]> <dbl[40]> 0.7894477
2 A 2015-2016 <dbl[40]> <dbl[40]> 0.2385581
3 B 2014-2015 <dbl[40]> <dbl[40]> 0.3084138
4 B 2015-2016 <dbl[40]> <dbl[40]> 0.2557849
我非常喜欢@MaksimGayduk 的解决方案。特别是 "trick" 和 summarise(values=list(value))
。以前没用过,感觉很有用。我的替代但类似的解决方案是基于 dplyr
和 broom
包。
不同之处在于 (a) 我首先使用感兴趣的 t.tests 的适当信息创建一个 table,然后我从初始 df
数据中调用相应的值帧,和 (b) 扫帚包 returns 来自 t.test 的所有信息输出为数据帧,您可以从中选择 p.value
或您需要的任何其他内容。
set.seed(15)
df <- data.frame(
group = c(rep('A', 120), rep('B', 120)),
year = rep(c(rep('2013-2014', 40), rep('2014-2015', 40), rep('2015-2016', 40)), 2),
value = rnorm(240)
)
library(dplyr)
library(broom)
df %>%
select(group, year) %>%
arrange(group,year) %>%
distinct() %>%
group_by(group) %>%
mutate(lag_year = lag(year)) %>%
filter(!is.na(lag_year)) %>%
group_by(group, year, lag_year) %>%
do(tidy(t.test(df$value[df$year==.$year & df$group==.$group],
df$value[df$year==.$lag_year & df$group==.$group])))
# Source: local data frame [4 x 11]
# Groups: group, year, lag_year [4]
#
# group year lag_year estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high
# (fctr) (fctr) (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
# 1 A 2014-2015 2013-2014 -0.14570115 0.04597952 0.19168066 -0.6752803 0.5016009 74.05084 -0.5756153 0.2842130
# 2 A 2015-2016 2014-2015 -0.02752882 0.01845069 0.04597952 -0.1162621 0.9077438 77.96192 -0.4989302 0.4438726
# 3 B 2014-2015 2013-2014 0.39565472 0.05703318 -0.33862155 1.5776920 0.1187303 77.10933 -0.1037022 0.8950116
# 4 B 2015-2016 2014-2015 -0.07423089 -0.01719771 0.05703318 -0.3048113 0.7613240 77.77704 -0.5590850 0.4106233
我有一个包含不同组、年份及其值的数据框,例如:
data <- data.frame(
group = c(rep('A', 120), rep('B', 120)),
year = rep(c(rep('2013-2014', 40), rep('2014-2015', 40), rep('2015-2016', 40)), 2),
value = rnorm(240)
)
对于每个组中的每一年,我想 运行 进行 t 检验以查看这些值是否与前几年有显着差异(我一直在使用函数 t.test(x, y, var.equal = TRUE) 一次性执行此操作)
我想 return 数据框和 p 值,或者最好是使用 gtools::stars.pval() 生成的重要星星。所以 return 类似下面的内容
group year significance
A 2013-2014 NA
A 2014-2015 **
A 2015-2016 ***
B 2013-2014 NA
B 2014-2015
B 2015-2016
其中,2014-2015 和 2013-2014 之间差异的 p 值对于 'A' 在 0.001 和 0.01 之间,而 2015-2015 和 2014-2015 之间差异的 p 值对于 A <0.001。没有证据表明 B.
在任何年份有任何显着差异不能保证每个组的年数都相同。
最好最快的方法是什么?我希望我可以按组和年份使用 dplyr 和 group_by 来做到这一点?
另一种选择是汇总数据框,将一个单元格中的所有值存储为列表(是的,您可以这样做 - 数据框可以在其中嵌套列表!)
使用 dplyr:
df=tbl_df(data)
df=arrange(df,group,year) %>% group_by(group,year) %>% summarise(values=list(value))
df=mutate(df,prev_values=lag(values))
df=group_by(df,group,year)
df=filter(df,!any(is.na(unlist(prev_values))))
df=mutate(df,p_value=t.test(unlist(values),unlist(prev_values),var.equal=TRUE)$p.value) %>% print
group year values prev_values p_value
1 A 2014-2015 <dbl[40]> <dbl[40]> 0.7894477
2 A 2015-2016 <dbl[40]> <dbl[40]> 0.2385581
3 B 2014-2015 <dbl[40]> <dbl[40]> 0.3084138
4 B 2015-2016 <dbl[40]> <dbl[40]> 0.2557849
我非常喜欢@MaksimGayduk 的解决方案。特别是 "trick" 和 summarise(values=list(value))
。以前没用过,感觉很有用。我的替代但类似的解决方案是基于 dplyr
和 broom
包。
不同之处在于 (a) 我首先使用感兴趣的 t.tests 的适当信息创建一个 table,然后我从初始 df
数据中调用相应的值帧,和 (b) 扫帚包 returns 来自 t.test 的所有信息输出为数据帧,您可以从中选择 p.value
或您需要的任何其他内容。
set.seed(15)
df <- data.frame(
group = c(rep('A', 120), rep('B', 120)),
year = rep(c(rep('2013-2014', 40), rep('2014-2015', 40), rep('2015-2016', 40)), 2),
value = rnorm(240)
)
library(dplyr)
library(broom)
df %>%
select(group, year) %>%
arrange(group,year) %>%
distinct() %>%
group_by(group) %>%
mutate(lag_year = lag(year)) %>%
filter(!is.na(lag_year)) %>%
group_by(group, year, lag_year) %>%
do(tidy(t.test(df$value[df$year==.$year & df$group==.$group],
df$value[df$year==.$lag_year & df$group==.$group])))
# Source: local data frame [4 x 11]
# Groups: group, year, lag_year [4]
#
# group year lag_year estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high
# (fctr) (fctr) (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
# 1 A 2014-2015 2013-2014 -0.14570115 0.04597952 0.19168066 -0.6752803 0.5016009 74.05084 -0.5756153 0.2842130
# 2 A 2015-2016 2014-2015 -0.02752882 0.01845069 0.04597952 -0.1162621 0.9077438 77.96192 -0.4989302 0.4438726
# 3 B 2014-2015 2013-2014 0.39565472 0.05703318 -0.33862155 1.5776920 0.1187303 77.10933 -0.1037022 0.8950116
# 4 B 2015-2016 2014-2015 -0.07423089 -0.01719771 0.05703318 -0.3048113 0.7613240 77.77704 -0.5590850 0.4106233