【问题标题】:Remove rows based on unique values across two columns根据跨两列的唯一值删除行
【发布时间】:2014-04-23 11:33:18
【问题描述】:

我从两个实验中获得了一些数据,其中参与者听了成对的音频,现在我试图获得一个较小的成对列表,其中片段只出现一次。这是我的数据示例,其中每一行代表一对:

data <- structure(c("38", "39", "48", "50", "55", "68", "143", "'00123_16_02 Firestarter_timbre.txt'", 
"'00123_16_02 Firestarter_timbre.txt'", "'00123_16_02 Firestarter_timbre.txt'", 
"'00123_16_02 Firestarter_timbre.txt'", "'00133_10_02 Loner_timbre.txt'", 
"'00133_10_02 Loner_timbre.txt'", "'00371_17_05 - Original_timbre.txt'", 
"'00133_10_02 Loner_timbre.txt'", "'00030_11_01 Get Your Snack On_timbre.txt'", 
"'00845_03_11 - Flying Lotus - Parisian Goldfish_timbre.txt'", 
"'01249_17_UMEK - Efortil_timbre.txt'", "'00030_11_01 Get Your Snack On_timbre.txt'", 
"'01300_08_02 - Clipper_timbre.txt'", "'01300_08_02 - Clipper_timbre.txt'", 
"MRHT", "MRHT", "MRHT", "MRHT", "MRHT", "MRHT", "MRHT", "12", 
"9", "14", "11", "14", "15", "12", "11", "12", "14", "15", "14", 
"14", "11", "2.75", "2.22222222222222", "2.21428571428571", "2.54545454545455", 
"2.28571428571429", "2.53333333333333", "2.25", "2.81818181818182", 
"3.25", "3.14285714285714", "2.93333333333333", "3.14285714285714", 
"3.07142857142857", "2.90909090909091", "0.621581560508061", 
"0.97182531580755", "1.25137287246211", "1.21355975243384", "0.994490316197694", 
"0.743223352957207", "1.05528970602217", "0.873862897505303", 
"0.753778361444409", "0.662993544131796", "1.03279555898864", 
"0.662993544131796", "0.997248963150875", "1.04446593573419"), .Dim = c(7L, 
10L), .Dimnames = list(NULL, c("pair.number", "Segment1", "Segment2", 
"category", "Rhythm.n", "Timbre.n", "Rhythm.mean", "Timbre.mean", 
"Rhythm.sd", "Timbre.sd")))

有没有办法获得一组对,其中段不会在“Segment1”和“Segment2”中重复?下面是它的样子:

structure(c("48", "55", "143", "'00123_16_02 Firestarter_timbre.txt'", 
"'00133_10_02 Loner_timbre.txt'", "'00371_17_05 - Original_timbre.txt'", 
"'00845_03_11 - Flying Lotus - Parisian Goldfish_timbre.txt'", 
"'00030_11_01 Get Your Snack On_timbre.txt'", "'01300_08_02 - Clipper_timbre.txt'", 
"MRHT", "MRHT", "MRHT", "14", "14", "12", "14", "14", "11", "2.21428571428571", 
"2.28571428571429", "2.25", "3.14285714285714", "3.14285714285714", 
"2.90909090909091", "1.25137287246211", "0.994490316197694", 
"1.05528970602217", "0.662993544131796", "0.662993544131796", 
"1.04446593573419"), .Dim = c(3L, 10L), .Dimnames = list(NULL, 
    c("pair.number", "Segment1", "Segment2", "category", "Rhythm.n", 
    "Timbre.n", "Rhythm.mean", "Timbre.mean", "Rhythm.sd", "Timbre.sd"
    )))

谢谢!

【问题讨论】:

  • 对于这些,我手动选择了包含独特片段的片段来制作配对。无论段列在哪个列中,都必须避免重复。

标签: r unique delete-row


【解决方案1】:

听起来您想要所谓的“匹配图” - 您的顶点是轨道,如果您成对聆听它们,则它们之间会出现一条边。然后,您需要找到一组不包含公共顶点的边(匹配) - 理想情况下可能是最大的此类(最大匹配)。

R 的 igraph 包中有一个函数可以帮助解决这个问题,称为 maximum.bipartite.matching - 您需要将 segment1 和 segment2 放入图形表示中才能调用它。大致如下:

seg1 <-df$Segment1
seg2 <- df$Segment2
levs <- unique(c(seg1, seg2))
seg1 <- as.integer(factor(seg1, levels=levs))
seg2 <- as.integer(factor(seg2, levels=levs))
library(igraph)
reord <- order(c(1:length(seg1), 1:length(seg2)))
gr <- graph(c(seg1, seg2)[reord])
maximum.bipartite.matching(gr)

这主要是为了以正确的格式获取顶点:我们将它们转换为具有共同水平的因子,然后将它们转换为整数。我们将它们交织形成 (seg1_1, seg2_1, seg1_2, seg2_2, seg1_3, seg2_3, ...) 以给出成对的顶点,然后从中创建一个图形对象。最后一行的输出将找到最大数量的音轨对,使得它们都不重叠。您需要提取这些数据,并将它们映射回原始数据集。

【讨论】:

  • 认为这可能是因为我没有将其设置为 bipartite 图,抱歉。如果您设置V(gr)$type &lt;- FALSE,该函数应该可以工作,尽管我会说应该找到三个边,而该函数似乎只找到三个 - 可能是人为地强制该图成为双向的结果。也许其他人知道 R 中更好的图匹配算法
  • 然后我得到以下错误:Error in .Call("R_igraph_create", as.numeric(edges) - 1, as.numeric(n), : At type_indexededgelist.c:117 : cannot create empty graph with negative number of vertices, Invalid value
  • 检查 seg1 和 seg2 是否得到正确的值 - 到第五行,它们应该是没有任何缺失值的整数。根据 Segment1 的确切类别,您最初可能需要将它们转换为 as.character(df$Segment1) 等
  • 而且我认为它提供的匹配是最大的,因为不能添加任何不会引入重叠的边缘 - 但它不一定找到“最大”最大集(称为相当混乱的 maxim_um_)- 我找不到这种算法的 R 实现
  • 感谢您花时间回答我的所有回复!运行此代码并索引回主数据库后,由于某种奇怪的原因,我仍然得到重复的值。我想我明天会寻找解决方案,并等待看看其他人是否有一些关于如何做到这一点的意见。
【解决方案2】:

编辑:第二行代码现在确保 Segment1 列中的任何内容都不会出现在 Segment2 列中。请注意,此解决方案可能返回的行数可能少于最大可能行数。

这确保了 Segement1 的值是唯一的:

data <- data[!duplicated(data[, "Segment1"]),]

然后您可以运行它来删除 Segment2 列中的重复项;这也将删除 Segment2 出现在 Segment1 列中的任何行:

data <- data[!duplicated(data[, "Segment2"]) & !(data[, "Segment2"] %in% data[, "Segment1"]),]

【讨论】:

  • 我用duplicated 玩了一段时间,但它仍然给我跨列 Segment1 和 Segment2 的重复值。你知道防止这种情况的方法吗?
猜你喜欢
  • 1970-01-01
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多