【问题标题】:R: join/merge of a table with two look-up tables based on a conditionR:根据条件连接/合并具有两个查找表的表
【发布时间】:2017-06-11 04:26:21
【问题描述】:

我有一个基本的人数据集:

everyoneexample <- data.frame(
gender=c("Female", "Male", "Male", "Female"), age=c(18, 18, 20, 21))

> everyoneexample
  gender age
1 Female  18
2   Male  18
3   Male  20
4 Female  21

还有两个查找表:

scorefemale <- data.frame(age=c(18, 19, 20, 21, 22, 23), 
  score=c(1.1, 3.3, 5.5, 7.7, 9.9, 11.1))

> scorefemale
  age score
1  18   1.1
2  19   3.3
3  20   5.5
4  21   7.7
5  22   9.9
6  23  11.1

scoremale <- data.frame(age=c(18, 19, 20, 21, 22, 23), 
   score=c(2.2, 4.4, `6.6, 8.8, 10.1, 12.1))`

> scoremale
  age score
1  18   2.2
2  19   4.4
3  20   6.6
4  21   8.8
5  22  10.1
6  23  12.1

我基本上是想得到这个:

    gender  age score
1   Female  18  1.1
2   Male    18  2.2
3   Male    20  6.6
4   Female  21  7.7

我在条件连接/合并上查找的所有内容都假定一个主表和一个引用表,但我的问题需要两个引用表。

希望这个例子很清楚,但如果你想让我澄清任何问题,请不要提出任何问题。

更新:感谢 Gregor,最优雅的答案似乎只是从两个参考表的 rbind 中创建一个临时表,然后使用两个 "通过”变量:

everyoneexample <- merge(scores_FandM, everyoneexample, by=c("age", "gender"))

【问题讨论】:

  • 要么 (a) 在每个查找表中添加 gender 列并使用两个左连接,要么 (b) 按性别拆分主表并将每个拆分连接到适当的查找,然后重新组合。我会推荐(a)。
  • 感谢 Gregor,我首先尝试了这个解决方案,因为它看起来干净优雅,但是我意识到尝试第二次 merge(),我的数据集正在制作单独的 score.x 和 score.y 列,所以我求助于内森的解决方案。我确信某处有一个简单的参数可以解决这个问题,但不是试图找到它,而是 Nathan 的答案已经可用......但是谢谢!
  • 最后,我确实最终使用了您的 (a) 解决方案。为了协调两个连接后形成的多个分数列,我必须执行 df$score
  • 可能会节省一些摆弄的轻微调整将是(1)将gender列添加到每个查找表,(2)rbind查找表一起,(3)加入主要数据。这意味着您只需要一个连接。
  • 谢谢 Gregor,这是最优雅的回答。

标签: r join merge conditional


【解决方案1】:
female_rows <- which(everyoneexample$gender == 'Female')
female_matches <- merge(everyoneexample[female_rows, ], scorefemale, by = 'age')

male_rows <- which(everyoneexample$gender == 'Male')
male_matches <- merge(everyoneexample[male_rows, ], scoremale, by = 'age')

everyoneexample$score <- NA
everyoneexample[female_rows, 'score'] <- female_matches$score
everyoneexample[male_rows, 'score'] <- male_matches$score

【讨论】:

  • 我刚刚在我的真实数据集上尝试了你的建议,我没有想到的一件事是我的实际数据表中有 age==NAs,我不得不在我的数据表中添加 age==NA 行参考表,但除此之外一切都很好。谢谢!
  • 深入研究数据,我发现它实际上并不正确。在只运行了女性部分之后,我在主数据集上运行了一个大的 dcast(everyoneexample, age~score, ...),虽然查找数据的性质对每个年龄都有一个独特的分数,但我看到了每个分数对大多数年龄的分布。 (1/2)
  • (2/2) 另外,查看主数据集,每个分数都以块的​​形式出现,例如,第一个分数(女性查找表中的年龄=15)与前四个每个人的女性行示例,无论年龄大小。然后,everyexample 中接下来的 100 个左右的 Female 行在 Female 查找表中具有下一个分数 (age=16),而与everyoneexample 表中的年龄无关。
【解决方案2】:

感谢@Gregor,他建议在每个查找表中添加一个 gender 列:

> scorefemale$gender <- "Female"
> scoremale$gender <- "Male"

然后将这些表组合成一个大查找表:

> scores_FandM <- rbind(scorefemale, scoremale)

然后最后使用两个“by”变量 - agegender 将主表与查找表左连接 - 有效地形成一个 复合键到新的组合查找表中:

> everyoneexample <- 
      merge(everyoneexample, scores_FandM, by=c('age', 'gender'), all.x = TRUE)

简单优雅...谢谢!

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多