Как отфильтровать строки, содержащие две конкретные символьные строки в разных (неуказанных) столбцах? - PullRequest
2 голосов
/ 08 апреля 2019

Учитывая набор из 8 имен, я хочу создать все уникальные комбинации из 5 имен.Однако некоторые имена могут не встречаться вместе.

Как мне отфильтровать строки, например, объединяющие "linda" и "susy" с учетом данных следующего примера?

# 7 names
names <- c("joe", "mark", "mary", "john", "linda", "susy", "peter", "annie")

# All unique combinations of 5 names
cbn <- t(combn(names, 5))

Фактические данные намного больше, и есть больше комбинаций, которые должны быть исключены.В идеале я хотел бы найти краткий и аккуратный способ сделать это так, чтобы мне пришлось как можно меньше корректировать код, если мне нужно внести изменения в исключения.

Ответы [ 2 ]

4 голосов
/ 08 апреля 2019

Вот небольшая функция с двумя аргументами: data и x, которая делает то, что вы ищете

f <- function(data, x) {
  data[rowSums(`dim<-`(data %in% x, dim(data))) < length(x), ]
}

Функция исключает строки, в которых значения в x отображаются вместе.

Использование

x <- c("linda", "susy")
f(cbn, x)

Результат

#      [,1]   [,2]   [,3]    [,4]    [,5]   
# [1,] "joe"  "mark" "mary"  "john"  "linda"
# [2,] "joe"  "mark" "mary"  "john"  "susy" 
# [3,] "joe"  "mark" "mary"  "john"  "peter"
# [4,] "joe"  "mark" "mary"  "john"  "annie"
# [5,] "joe"  "mark" "mary"  "linda" "peter"
# [6,] "joe"  "mark" "mary"  "linda" "annie"
# [7,] "joe"  "mark" "mary"  "susy"  "peter"
# [8,] "joe"  "mark" "mary"  "susy"  "annie"
# [9,] "joe"  "mark" "mary"  "peter" "annie"
#[10,] "joe"  "mark" "john"  "linda" "peter"
#[11,] "joe"  "mark" "john"  "linda" "annie"
#[12,] "joe"  "mark" "john"  "susy"  "peter"
#[13,] "joe"  "mark" "john"  "susy"  "annie"
#[14,] "joe"  "mark" "john"  "peter" "annie"
#[15,] "joe"  "mark" "linda" "peter" "annie"
#[16,] "joe"  "mark" "susy"  "peter" "annie"
#[17,] "joe"  "mary" "john"  "linda" "peter"
#[18,] "joe"  "mary" "john"  "linda" "annie"
#[19,] "joe"  "mary" "john"  "susy"  "peter"
#[20,] "joe"  "mary" "john"  "susy"  "annie"
#[21,] "joe"  "mary" "john"  "peter" "annie"
#[22,] "joe"  "mary" "linda" "peter" "annie"
#[23,] "joe"  "mary" "susy"  "peter" "annie"
#[24,] "joe"  "john" "linda" "peter" "annie"
#[25,] "joe"  "john" "susy"  "peter" "annie"
#[26,] "mark" "mary" "john"  "linda" "peter"
#[27,] "mark" "mary" "john"  "linda" "annie"
#[28,] "mark" "mary" "john"  "susy"  "peter"
#[29,] "mark" "mary" "john"  "susy"  "annie"
#[30,] "mark" "mary" "john"  "peter" "annie"
#[31,] "mark" "mary" "linda" "peter" "annie"
#[32,] "mark" "mary" "susy"  "peter" "annie"
#[33,] "mark" "john" "linda" "peter" "annie"
#[34,] "mark" "john" "susy"  "peter" "annie"
#[35,] "mary" "john" "linda" "peter" "annie"
#[36,] "mary" "john" "susy"  "peter" "annie"

Вы можете использовать цикл for, когда вам нужно многократно проверять несколько комбинаций

x <- c("linda", "susy")
y <- c("joe", "john")

Создать список с этими комбинациями

combs <- list(x, y)

Применить f (сверху) в цикле

for(i in 1:length(combs)) {
  cbn <- f(cbn, combs[[i]])
}

Результат

cbn
#      [,1]   [,2]   [,3]    [,4]    [,5]   
# [1,] "joe"  "mark" "mary"  "linda" "peter"
# [2,] "joe"  "mark" "mary"  "linda" "annie"
# [3,] "joe"  "mark" "mary"  "susy"  "peter"
# [4,] "joe"  "mark" "mary"  "susy"  "annie"
# [5,] "joe"  "mark" "mary"  "peter" "annie"
# [6,] "joe"  "mark" "linda" "peter" "annie"
# [7,] "joe"  "mark" "susy"  "peter" "annie"
# [8,] "joe"  "mary" "linda" "peter" "annie"
# [9,] "joe"  "mary" "susy"  "peter" "annie"
#[10,] "mark" "mary" "john"  "linda" "peter"
#[11,] "mark" "mary" "john"  "linda" "annie"
#[12,] "mark" "mary" "john"  "susy"  "peter"
#[13,] "mark" "mary" "john"  "susy"  "annie"
#[14,] "mark" "mary" "john"  "peter" "annie"
#[15,] "mark" "mary" "linda" "peter" "annie"
#[16,] "mark" "mary" "susy"  "peter" "annie"
#[17,] "mark" "john" "linda" "peter" "annie"
#[18,] "mark" "john" "susy"  "peter" "annie"
#[19,] "mary" "john" "linda" "peter" "annie"
#[20,] "mary" "john" "susy"  "peter" "annie"
0 голосов
/ 09 апреля 2019

Другое решение:

Создание имен и комбинаций

names <- c("joe", "mark", "mary", "john", "linda", "susy", "peter", "annie")
cbn <- combn(names, 5)

Исключить строки с парами

csums <- colSums((cbn == "linda") + (cbn == "susy"))
csums_2 <- colSums((cbn == "joe") + (cbn == "john"))
cbn <- t(cbn[, csums < 2 & csums_2 <2])

Результаты:

> cbn
      [,1]   [,2]   [,3]    [,4]    [,5]   
 [1,] "joe"  "mark" "mary"  "linda" "peter"
 [2,] "joe"  "mark" "mary"  "linda" "annie"
 [3,] "joe"  "mark" "mary"  "susy"  "peter"
 [4,] "joe"  "mark" "mary"  "susy"  "annie"
 [5,] "joe"  "mark" "mary"  "peter" "annie"
 [6,] "joe"  "mark" "linda" "peter" "annie"
 [7,] "joe"  "mark" "susy"  "peter" "annie"
 [8,] "joe"  "mary" "linda" "peter" "annie"
 [9,] "joe"  "mary" "susy"  "peter" "annie"
[10,] "mark" "mary" "john"  "linda" "peter"
[11,] "mark" "mary" "john"  "linda" "annie"
[12,] "mark" "mary" "john"  "susy"  "peter"
[13,] "mark" "mary" "john"  "susy"  "annie"
[14,] "mark" "mary" "john"  "peter" "annie"
[15,] "mark" "mary" "linda" "peter" "annie"
[16,] "mark" "mary" "susy"  "peter" "annie"
[17,] "mark" "john" "linda" "peter" "annie"
[18,] "mark" "john" "susy"  "peter" "annie"
[19,] "mary" "john" "linda" "peter" "annie"
[20,] "mary" "john" "susy"  "peter" "annie"
...