如何将数据帧的值与另一个数据帧中的值进行比较?

时间:2016-05-01 12:08:43

标签: r dataframe comparison

几天前我发布了这个问题,但我被告知我的描述太混乱了。然而,在澄清我的问题并添加一个例子之后,这个问题没有得到任何进一步的关注。由于我仍然需要一个解决方案,我删除了旧问题,现在将其发布为希望更好的表述。

以下示例说明了我的问题。

我有两个对象。其中第一个是描述每个人( id )组( id )的数据框,这是s(他)采取行动的一年( do.year )以及2010年至2015年之间每年的变量值( var )( 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 组的数据框,还包含每年之间变量( var )的值2010年和2015年( 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 ),我想在采取行动的一年中采用变量( var )的值( do.year )并从该值中减去同年的组平均值( av 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解决方案将是首选。

1 个答案:

答案 0 :(得分:3)

如果你想要一个data.table解决方案,那么这是一个可能的解决方案。我建议您先将列表转换为data.tablegroup。只需var.yeargroup加入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
相关问题