我有一个包含3个因子和一些数字的数据框,其结构类似于:
year <- as.factor(rep(c(2006, 2006, 2006, 2006, 2006, 2007, 2007, 2007,
2007, 2007), 40))
seller <- rep(c("Alfred", "Betty", "Charles", "Debbie", "Ed"), 80)
region <- rep(c("North", "North", "North", "South", "South", "North",
"North", "South"), 50)
sale <- rnorm(400, mean = 60, sd = 10) # Quick way to get fake data
data <- data.frame(year=year, seller=seller, region=region, sale=sale)
(我感兴趣的实际数据框相当于约20,000个销售,超过13年,以及6个地区,有50个左右的卖家,所以我不会在这里包含它。)我需要对每对卖家进行成对的 t - 测试比较,按年份和地区划分。 (例如,对于这个样本数据框架,我需要4组不同的成对比较:2006年和北方,2007年和北方,2006年和南方,2007年和南方的所有卖家相互比较。会有10个成对的 t - 测试:Alfred和Betty,Alfred和Charles等等。)作为一个老C / C ++程序员(和相对较新的R程序员),我可以设置几个for循环,循环遍历年度因子,然后是区域因子,对该年和该区域的数据框进行子集化,然后执行&amp;打印/存储卖家之间的所有成对t检验。
然而,我试图弄清楚如何在没有for循环的情况下做到这一点。我试图使用其中一个apply
- 族函数。我可以编写一个函数来执行 t -tests,并使用FUN = function
,但我似乎无法将两个for循环转换为一个INDEX for apply-family目的。到目前为止我所做的所有努力,例如使用&#34; list(地区,年份)&#34;作为索引,导致明显的错误:&#34;参数必须具有相同的长度&#34;,更不用说这种特殊的方法不能同时根据需要应用BOTH过滤器。我已经和expand.grid()
玩了一些帮助,但我不认为任何最终的矢量化都会让我得到我想要的东西。
如果没有for循环,有没有办法做到这一点?我觉得我错过了一些东西,但我找不到它;我很感激你的任何帮助,即使帮助说的是#34; apply
- 家庭是错误的地方,你应该去data.table
或{{1} }&#34 ;. (但是,我对在base-R中可以完成的任何事情特别感兴趣,但这主要是因为探索base-R是我现在正在玩的游戏。)
答案 0 :(得分:1)
year <- as.factor(rep(c(2006, 2006, 2006, 2006, 2006, 2007, 2007, 2007, 2007, 2007), 40))
seller <- rep(c("Alfred", "Betty", "Charles", "Debbie", "Ed"), 80)
region <- rep(c("North", "North", "North", "South", "South", "North", "North", "South"), 50)
sale <- rnorm(400, mean = 60, sd = 10) # Quick way to get fake data
data <- data.frame(year=year, seller=seller, region=region, sale=sale)
list.sellers.combn <- combn(c("Alfred", "Betty", "Charles", "Debbie", "Ed"), 2, simplify = FALSE)
df.region.year <- expand.grid(region = c("North", "South"), year = 2006:2007)
df.combn <- do.call(rbind, lapply(list.sellers.combn, function(n) {
df.region.year[,"seller1"] <- n[1]
df.region.year[,"seller2"] <- n[2]
df.region.year}))
list.ttest.results <- lapply(1:nrow(df.combn), function(n) {
vec <- df.combn[n,]
df.data <- data[data[,"region"] == vec[,"region"] & data[,"year"] == vec[,"year"] & data[,"seller"] %in% unlist(vec[,c("seller1", "seller2")]),]
df.ttest <- df.data[,c("seller", "sale")]
result.ttest <- with(df.ttest, t.test(sale[seller == unique(seller)[1]], sale[seller == unique(seller)[2]]))
result.ttest})