Как выполнить проверку перестановки «на лету», не сохраняя результат в R - PullRequest
1 голос
/ 16 января 2020

Предположим, у нас есть следующие перестановки букв "a", "b" и "c":

library(combinat)
do.call(rbind, permn(letters[1:3]))
#      [,1] [,2] [,3]
# [1,] "a"  "b"  "c" 
# [2,] "a"  "c"  "b" 
# [3,] "c"  "a"  "b" 
# [4,] "c"  "b"  "a" 
# [5,] "b"  "c"  "a" 
# [6,] "b"  "a"  "c" 

Возможно ли выполнить некоторую функцию для данной перестановки "на -the-fly "(т.е. конкретная строка) без сохранения результата?

То есть, если row == "a" "c" "b" или row == "b" "c" "a", не сохраните результат. В этом случае желаемый результат будет:

#      [,1] [,2] [,3]
# [1,] "a"  "b"  "c" 
# [2,] "c"  "a"  "b" 
# [3,] "c"  "b"  "a" 
# [4,] "b"  "a"  "c" 

Я знаю, что могу применить функцию ко всем перестановкам на лету в пределах combinat::permn с аргументом fun, таким как:

permn(letters[1:3], fun = function(x) {
  res <- paste0(x, collapse = "")
  if (res == "acb" | res == "bca") {
    return(NA)
  } else {
    return(res)
  }
})

Но в этом кадре хранится NA, и возвращенный список содержит 6 элементов вместо желаемых 4 элементов:

# [[1]]
# [1] "abc"
# 
# [[2]]
# [1] NA
# 
# [[3]]
# [1] "cab"
# 
# [[4]]
# [1] "cba"
# 
# [[5]]
# [1] NA
# 
# [[6]]
# [1] "bac"

Примечание. Меня не интересует последующее удаление значений NA; Я особенно заинтересован в том, чтобы не добавлять список результатов «на лету» для данной перестановки.

Ответы [ 2 ]

2 голосов
/ 16 января 2020

Мы могли бы использовать конвейер magrittr, где мы привязываем входную матрицу к проверяемым строкам и пропускаем повторяющиеся строки.

library(combinat)
library(magrittr)

Rows <- rbind(c("a", "c", "b"), c("b", "c", "a"))

do.call(rbind, permn(letters[1:3])) %>% 
  subset(tail(!duplicated(rbind(Rows, .)), -nrow(Rows)))

, давая:

     [,1] [,2] [,3]
[1,] "a"  "b"  "c" 
[2,] "c"  "a"  "b" 
[3,] "c"  "b"  "a" 
[4,] "b"  "a"  "c" 
1 голос
/ 16 января 2020

Вы можете return NULL для конкретного условия, которое хотите игнорировать, и rbind результата, который будет игнорировать элементы NULL и связывать только те комбинации, которые вам нужны.

do.call(rbind, combinat::permn(letters[1:3], function(x) 
   if(!all(x == c("a", "c", "b") | x == c("b", "c", "a")))
   return(x)
))

#    [,1] [,2] [,3]
#[1,] "a"  "b"  "c" 
#[2,] "c"  "a"  "b" 
#[3,] "c"  "b"  "a" 
#[4,] "b"  "a"  "c" 

Аналогично,

do.call(rbind, permn(letters[1:3],function(x) { 
   res <- paste0(x, collapse = "")
  if (!res %in% c("acb","bca")) 
    return(res) 
}))

#      [,1] 
#[1,] "abc"
#[2,] "cab"
#[3,] "cba"
#[4,] "bac"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...