R (%>%) не работает с функцией репликации

Я пытаюсь узнать функцию трубопровода (% > %).
При попытке конвертировать из этой строки кода в другую строку это не сработает.

---- R-код - оригинальная версия -----

set.seed(1014)
replicate(6,sample(1:8))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    7    4    5    1
[2,]    2    8    4    2    4    2
[3,]    5    4    8    5    8    5
[4,]    3    1    2    1    1    7
[5,]    4    6    3    7    7    3
[6,]    6    5    1    3    3    8
[7,]    8    7    5    8    6    6
[8,]    7    2    6    6    2    4

---- R-код - перекодирован с помощью трубки ----

> sample(1:8) %>%  replicate(6,.)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    7    7    7    7    7    7
[2,]    3    3    3    3    3    3
[3,]    2    2    2    2    2    2
[4,]    1    1    1    1    1    1
[5,]    5    5    5    5    5    5
[6,]    4    4    4    4    4    4
[7,]    8    8    8    8    8    8
[8,]    6    6    6    6    6    6

Обратите внимание, что при использовании труб выборка не работает, давая мне один и тот же вектор.

Ответы

Ответ 1

Чего ожидать. replicate ожидает выражение, но при использовании оператора pipe, поскольку вы просто вставляете результат вызова sample() в replicate. Таким образом, вы получаете 6-кратный результат.

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

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% 
  replicate(6, .) %>%
  sapply(eval)

дает:

    [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    5    2   10   10    9    2
[2,]    4    3    1    3  -99    1
[3,]   10    2    3    8    2    4
[4,]  -99    1    6    2   10    3
[5,]    8  -99    1    9    4    6
[6,]    4   10    8    1  -99    8

Что здесь происходит:

  • посылает сообщения и выражение для репликации, не оценивая его.
  • replicate реплицирует это выражение и возвращает список с 6-кратным выражением, но без его оценки.
  • sapply (eval) проходит через список и выполняет каждое выражение в этом списке.

В предыдущем вопросе (т.е. при использовании data.frame) вы могли бы сделать, например:

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% 
  replicate(6, .) %>%
  data.frame

Теперь функция data.frame заставит выполнять выражения, но вы также получите ужасные имена переменных, т.е. само выражение.

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

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

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% {
  replicate(6, eval(.)) }

Очень интересно, но imho не очень полезно...