【问题标题】:R - delete rows providing a specific combination of valuesR - 删除提供特定值组合的行
【发布时间】:2017-03-29 05:33:15
【问题描述】:

我有一个包含 100 个对象的列表,我使用它们创建了所有可能的对象对

pairs <- t(combn(my_objects, 2))

但是 A 组的任何对象都不能与 B 组的任何对象组合。 表示如果

group_A <- c(5:10)
group_B <- c(50:55)

应该删除一对 6 和 55,无论它们在哪一行。 5和6的组合是可以的。 如何检查每一行是否有这些“禁止”对之一并将其删除?我尝试了%in%,但我不知道如何将它用于多个对象。

编辑

我真正的问题是这样的: 我有一个 75 个字符的列表,A1 ... A75。它们应该组合成对。但是 group_A (5...10) 之一不应与 group_B (50...55) 之一结合。

第二步:pairs中的一行可以是:A1.A8 - A2.A.12.A51。这对也应该被删除。

我的数据框是:

 pairs <- cbind (c("A1", "A9.A3", "A5", "A52.A12", "A8"), 
               c("A76.A14", "A50", "A2.A7", "A70", "A50.A51"))

group_A <- c("A5", "A6" "A7", "A8", "A9", "A10")
group_B <- c("A50", "A51", "A52", "A53", "A54", "A55")

我的目标 - 从pairsdata 框架中删除 group_A 和 group_B 项的所有组合。这样pairs =

     [,1] [,2]     
[1,] "A1" "A76.A14"
[2,] "A5" "A2.A7"  
[3,] "A52.A12" "A70" 

【问题讨论】:

  • 请展示一个可重现的例子和预期的输出

标签: r subset


【解决方案1】:

我们可以使用expand.gridpaste创建一个vector的组合,检查这些元素是否存在%in%vectorcombn创建的,否定(!)和子集'pairs' 与这个逻辑向量。

v1 <- combn(length(my_objects), 2, FUN = paste, collapse=" ")
pairs[!v1 %in% do.call(paste, expand.grid(group_A, group_B)),]

【讨论】:

  • 嗯,不,它不工作。 pairs长度不变,存在禁止组合
  • @Miguel123 我创建了set.seed(24);my_objects &lt;- sample(1:200, 100, replace=FALSE),它对我有用dim(pairs) #[1] 4950 2dim(pairs[!v1 %in% do.call(paste, expand.grid(group_A, group_B)),])#[1] 4914 2
  • 嗯好吧,我的对象总是有一个字母作为前缀。这可能是问题吗?
  • @Miguel123 如果你的 my_objects 是一个长度为 100 的向量,它应该可以工作
  • 不,不是。这是一个 75 个字符的列表。我试图尽可能简化地提出问题,以便其他人可能会看到与他们的问题相似的地方。抱歉,如果那不正确。我将编辑我的问题并添加我真正的问题
【解决方案2】:

这不是很优雅,但是(我认为)它可以满足您的要求:对于每一行,将每列中的条目按字符“。”拆分,然后检查是否与 group_A 或 group_B 有任何重叠,如果是的话,将行索引添加到要删除的行的向量中:

rm_idx <- c()
for (r in 1:nrow(pairs)) {  # for each row of pairs...
  pair_A <- unlist(strsplit(pairs[r,1],'[.]')) # split first element by '.'
  pair_B <- unlist(strsplit(pairs[r,2],'[.]')) # split second elemnt by '.'
  l_A <- length(intersect( group_A,  pair_A)) # elements of group_A in pair_A
  l_B <- length(intersect( group_B,  pair_B)) # elements of group_A in pair_A
  if (l_A > 0 & l_B > 0) { # if there is overlap in both entries of that row --> remove
    rm_idx <- c(rm_idx, r)
  }
}
new_pairs <- pairs[-rm_idx,]    

或者,您可以创建一个可与grepl 一起使用的正则表达式,以查找字符串中任何出现的元素,例如group_A

# concatenate vector of strings (with '|'), creating a regular expression for
# searching for any of them (using grep/grepl)
grp2reg <- function (g) {
  paste(g, collapse ='|')
}

# append dot to string (or each of a vector of strings)
add_dot <- function(g) {
  paste(g, '.', sep='')
}

# find strings from group_A/group_B in first/second column of pairs
idx_A <- grepl(grp2reg(add_dot(group_A)), add_dot(pairs[,1]) )
idx_B <- grepl(grp2reg(add_dot(group_B)), add_dot(pairs[,2]) )

# remove rows with a match in both columns
pairs_new <- pairs[!(idx_A & idx_B),]

注意附加'.'为了避免“找到”,例如A5A50 中,所有字符串都是必要的。所以,group_A 的正则表达式实际上是"A5.|A6.|A7.|A8.|A9.|A10.",并且点也附加到pairs 的元素上(例如,在A50.A5. 中查找A5.)。

【讨论】:

  • 嗨@Miguel123,这是否回答了您的问题?在任何一种情况下,您都会做出反应。
猜你喜欢
  • 2019-05-11
  • 1970-01-01
  • 2022-12-10
  • 1970-01-01
  • 2014-10-12
  • 2020-10-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多