【问题标题】:Merge producing unexpected results in R合并在 R 中产生意想不到的结果
【发布时间】:2012-01-05 23:25:48
【问题描述】:

我正在尝试合并:

to_graph <- structure(list(Teacher = c("BS", "BS", "FA"
), Level = structure(c(2L, 1L, 1L), .Label = c("BE", "AE", "ME", 
"EE"), class = "factor"), Count = c(2L, 25L, 28L)), .Names = c("Teacher", 
"Level", "Count"), row.names = c(NA, 3L), class = "data.frame")

graph_avg <- structure(list(Teacher = structure(c(1L, 1L, 2L), .Label = c("BS", 
"FA"), class = "factor"), Count.Fraction = c(0.0740740740740741, 
0.925925925925926, 1)), .Names = c("Teacher", "Count.Fraction"
), row.names = c(NA, -3L), class = "data.frame")

使用merge(to_graph, graph_avg, by="Teacher"),但没有得到我期望的结果(3 行),而是得到:

  Teacher Level Count Count.Fraction
1      BS    AE     2     0.07407407
2      BS    AE     2     0.92592593
3      BS    BE    25     0.07407407
4      BS    BE    25     0.92592593
5      FA    BE    28     1.00000000

有什么想法吗?谢谢!

【问题讨论】:

  • 抱歉,3 行。我在考虑另一个数据集。

标签: r data-management


【解决方案1】:

不确定您要完成什么。 merge 正在做它应该做的事情。

让我们看看所有的data.frames

graph_avg
  Teacher Count.Fraction
1      BS     0.07407407
2      BS     0.92592593
3      FA     1.00000000

to_graph
  Teacher Level Count
1      BS    AE     2
2      BS    BE    25
3      FA    BE    28

merge(to_graph, graph_avg)
  Teacher Level Count Count.Fraction
1      BS    AE     2     0.07407407
2      BS    AE     2     0.92592593
3      BS    BE    25     0.07407407
4      BS    BE    25     0.92592593
5      FA    BE    28     1.00000000

现在,如果我要合并这些,我必须查看哪些是常见的,以及我将获得什么以获得结果。老师,你两个都有。但是,如果我试图合并只是老师,我该怎么办? BS 没有唯一标识符,它在两个 data.frame 中出现两次。如果它在其中一个中出现一次,那将很容易解决。所以,我可以检查并说,好的,我在一个 data.frame 中拥有一个唯一标识符,级别......可以做到......然后去做一些不会丢失任何数据的东西。 merge 对于您有一个小数据框架的情况非常方便,比如每个老师都在其中一次,并且那里有老师的年龄或性别。您可以将其合并到另一个 data.frame 中,对老师进行重复测量,每次老师出现时,您也会知道这些。但是对于您正在做的事情,它不是正确的工具。

merge 不是你想要的。如果这些确实是您的 data.frames,请改用 cbind

cbind(to_graph, graph_avg$Count.Fraction)

  Teacher Level Count Count.Fraction
1      BS    AE     2     0.07407407
2      BS    BE    25     0.92592593
3      FA    BE    28     1.00000000

这可能就是你要找的东西。

【讨论】:

  • 但是,cbind() 解决方案的缺点是您需要绝对 100% 确保 to_graph$Teachergraph_avg$Teacher 的顺序相同,否则您最终会连接给老师的数字错误!在这个玩具示例中,这是微不足道的,但在更大的数据集中,这很容易被忽略。因此,尽管我重视您对merge() 方法的解释,但我希望merge() 参数的神奇组合不会导致行重复。到目前为止,我找不到它。所以我想你是正确的声称这是出于`merge
  • 您所要求的没有解决方案。请询问更具体的内容,这可以通过算法解决。您需要一种方法来识别至少一个 data.frame 中的唯一教师,否则问题无法解决,除非您使用 order...并且只有在 data.frames 长度相同的情况下。这不是merge 命令的问题,而是逻辑问题。如果您告诉我我不能依赖顺序,那么如果没有更多信息,我根本无法将您的数据合并在一起。
  • +1 @John,我同意您对为什么 merge 无法使用所提供的数据的分析。但是,正如我在回答中所建议的那样,我认为 OP 应该以不同的方式进行分析。
【解决方案2】:

由于很明显您的一个数据集是从另一个数据集派生的,我建议您根本不需要合并,而是找到一种方法进行分析,使所有数据保持完整.

例如,使用包plyr 中的ddply 从另一组派生一组。请注意此结果如何包含您需要的所有信息:

> library(plyr)
> ddply(to_graph, .(Teacher), transform, Count.Fraction=Count/sum(Count))

  Teacher Level Count Count.Fraction
1      BS    AE     2     0.07407407
2      BS    BE    25     0.92592593
3      FA    BE    28     1.00000000

回答您关于合并的问题。 R 中的merge 类似于数据库join。要连接两个表,您需要确定可以匹配两个表中的主键。在您的情况下,主键是TeacherLevel 的组合。由于Level 列在您的第二个data.frame 中不存在,因此merge 是不可能的。

恢复这种情况的唯一方法是将丢失的主键位添加回数据中。假设数据以完全相同的顺序排序,您可以使用cbind 执行此操作,然后执行merge

> merge(to_graph, cbind(graph_avg, Level=to_graph$Level))
  Teacher Level Count Count.Fraction
1      BS    AE     2     0.07407407
2      BS    BE    25     0.92592593
3      FA    BE    28     1.00000000

【讨论】:

  • 很好地了解了 Count.Fraction 的来源。我什至没有费心去评估。虽然,在已知的情况下,合并将与复制的另一列一起工作,无论是计数还是级别。
  • @John 将 Count 添加为主键将适用于示例数据,但不会泛化 - 如果两个不同级别的 Count 相同会发生什么情况?
猜你喜欢
  • 2019-04-05
  • 1970-01-01
  • 2023-03-24
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 2011-06-04
相关资源
最近更新 更多