我几天前发布了这个问题,但有人告诉我我的描述太混乱了。但是,在澄清了我的问题并添加了示例之后,该问题没有得到任何进一步的关注。由于我仍然需要一个解决方案,因此我删除了旧问题,现在将其发布为希望更好的表述形式。
以下示例说明了我的问题。
我有两个对象。首先是一个数据框,描述每个人的(id)组(group),s(he)采取行动的年份(do.year)以及2010年至2010年之间每年的变量值(var)。 2015(var.year)。
set.seed(1)
df <- data.frame(
id = rep(1:3, each = 6),
group = c(rep("a", 12), rep("b", 6)),
do.year = rep(sample(2011:2013), each = 6),
var = runif(18),
var.year = 2010:2015)
df
id group do.year var var.year
1 1 a 2011 0.90820779 2010
2 1 a 2011 0.20168193 2011
3 1 a 2011 0.89838968 2012
4 1 a 2011 0.94467527 2013
5 1 a 2011 0.66079779 2014
6 1 a 2011 0.62911404 2015
7 2 a 2013 0.06178627 2010
8 2 a 2013 0.20597457 2011
9 2 a 2013 0.17655675 2012
10 2 a 2013 0.68702285 2013
11 2 a 2013 0.38410372 2014
12 2 a 2013 0.76984142 2015
13 3 b 2012 0.49769924 2010
14 3 b 2012 0.71761851 2011
15 3 b 2012 0.99190609 2012
16 3 b 2012 0.38003518 2013
17 3 b 2012 0.77744522 2014
18 3 b 2012 0.93470523 2015
第二个对象由组a和b的数据框组成,还包含2010年至2015年之间每年的变量(var)值(var.year),但这是组成员的平均值。它是数据帧的列表,但如有必要,也可以将其转换为单个数据帧。
avg <- list(
"a" = data.frame(var.year = 2010:2015, var = runif(6)),
"b" = data.frame(var.year = 2010:2015, var = runif(6)))
avg
$a
var.year var
1 2010 0.21214252
2 2011 0.65167377
3 2012 0.12555510
4 2013 0.26722067
5 2014 0.38611409
6 2015 0.01339033
$b
var.year var
1 2010 0.3823880
2 2011 0.8696908
3 2012 0.3403490
4 2013 0.4820801
5 2014 0.5995658
6 2015 0.4935413
我的目标是在特定年份(do.year)中将每个人的结果指标与各个比较组的结果指标进行比较。因此,对于每个个体(id),我想取采取行动的年份(do.year)中的变量(var)的值,然后从该值中减去组平均值(var在avg中)同年(var.year)。每个人的结果将存储在新变量diff.var中。
我只有几周的R经验,所以我的解决方案是只合并每个组(和变量)的数据集,然后进行计算(如下)。但是,由于我的原始数据集涉及7个组和6个变量,因此将导致大约1000行代码。我也尝试了循环,但是无法在各处正确定义循环变量。
df.a <- merge(df, avg[["a"]], by = "var.year")
df.a$diff.var[df.a$group == "a" & df.a$var.year == df.a$do.year] <-
df.a$var.x[df.a$group == "a" & df.a$var.year == df.a$do.year] -
df.a$var.y[df.a$group == "a" & df.a$var.year == df.a$do.year]
df.a
var.year id group do.year var.x var.y diff.var
1 2010 1 a 2011 0.90820779 0.21214252 NA
2 2010 2 a 2013 0.06178627 0.21214252 NA
3 2010 3 b 2012 0.49769924 0.21214252 NA
4 2011 1 a 2011 0.20168193 0.65167377 -0.4499918
5 2011 2 a 2013 0.20597457 0.65167377 NA
6 2011 3 b 2012 0.71761851 0.65167377 NA
7 2012 1 a 2011 0.89838968 0.12555510 NA
8 2012 2 a 2013 0.17655675 0.12555510 NA
9 2012 3 b 2012 0.99190609 0.12555510 NA
10 2013 1 a 2011 0.94467527 0.26722067 NA
11 2013 2 a 2013 0.68702285 0.26722067 0.4198022
12 2013 3 b 2012 0.38003518 0.26722067 NA
13 2014 1 a 2011 0.66079779 0.38611409 NA
14 2014 2 a 2013 0.38410372 0.38611409 NA
15 2014 3 b 2012 0.77744522 0.38611409 NA
16 2015 1 a 2011 0.62911404 0.01339033 NA
17 2015 2 a 2013 0.76984142 0.01339033 NA
18 2015 3 b 2012 0.93470523 0.01339033 NA
df.b <- merge(df, avg[["b"]], by = "var.year")
df.b$diff.var[df.b$group == "b" & df.b$var.year == df.b$do.year] <-
df.b$var.x[df.b$group == "b" & df.b$var.year == df.b$do.year] -
df.b$var.y[df.b$group == "b" & df.b$var.year == df.b$do.year]
df.b
var.year id group do.year var.x var.y diff.var
1 2010 1 a 2011 0.90820779 0.3823880 NA
2 2010 2 a 2013 0.06178627 0.3823880 NA
3 2010 3 b 2012 0.49769924 0.3823880 NA
4 2011 1 a 2011 0.20168193 0.8696908 NA
5 2011 2 a 2013 0.20597457 0.8696908 NA
6 2011 3 b 2012 0.71761851 0.8696908 NA
7 2012 1 a 2011 0.89838968 0.3403490 NA
8 2012 2 a 2013 0.17655675 0.3403490 NA
9 2012 3 b 2012 0.99190609 0.3403490 0.6515571
10 2013 1 a 2011 0.94467527 0.4820801 NA
11 2013 2 a 2013 0.68702285 0.4820801 NA
12 2013 3 b 2012 0.38003518 0.4820801 NA
13 2014 1 a 2011 0.66079779 0.5995658 NA
14 2014 2 a 2013 0.38410372 0.5995658 NA
15 2014 3 b 2012 0.77744522 0.5995658 NA
16 2015 1 a 2011 0.62911404 0.4935413 NA
17 2015 2 a 2013 0.76984142 0.4935413 NA
18 2015 3 b 2012 0.93470523 0.4935413 NA
如何在R中解决此问题?基本R或data.table解决方案将是首选。
如果您想要一种data.table
解决方案,那么这里可能是一个解决方案。我建议先将您的列表转换为data.table
带有group
列的。而只是做一个连接上var.year
,并group
同时do.year == var.year
创造diff.var
的飞行。我还假设您不是真正在为每个组创建相同的数据集,而是avg
根据您的规则仅将原始数据集加入其中。类似于以下内容
library(data.table)
### Create a group column for each list and convert to a data.table
avg <- rbindlist(Map(cbind, avg, group = names(avg)))
### join by var.year and group while do.year == var.year and create diff.var on the fly
setDT(df)[do.year == var.year,
diff.var := var - avg[copy(.SD), var, on = c("var.year", "group")]]
df
# id group do.year var var.year diff.var
# 1: 1 a 2011 0.90820779 2010 NA
# 2: 1 a 2011 0.20168193 2011 -0.4499918
# 3: 1 a 2011 0.89838968 2012 NA
# 4: 1 a 2011 0.94467527 2013 NA
# 5: 1 a 2011 0.66079779 2014 NA
# 6: 1 a 2011 0.62911404 2015 NA
# 7: 2 a 2013 0.06178627 2010 NA
# 8: 2 a 2013 0.20597457 2011 NA
# 9: 2 a 2013 0.17655675 2012 NA
# 10: 2 a 2013 0.68702285 2013 0.4198022
# 11: 2 a 2013 0.38410372 2014 NA
# 12: 2 a 2013 0.76984142 2015 NA
# 13: 3 b 2012 0.49769924 2010 NA
# 14: 3 b 2012 0.71761851 2011 NA
# 15: 3 b 2012 0.99190609 2012 0.6515571
# 16: 3 b 2012 0.38003518 2013 NA
# 17: 3 b 2012 0.77744522 2014 NA
# 18: 3 b 2012 0.93470523 2015 NA
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句