Як уже зазначалося, vapply
робить дві речі:
- Невелике поліпшення швидкості
- Покращує узгодженість, забезпечуючи обмежені перевірки типу повернення.
Другий момент - більша перевага, оскільки він допомагає ловити помилки до того, як вони трапляються, і веде до більш надійного коду. Цю перевірку поверненого значення можна зробити окремо, скориставшись sapply
наступним, stopifnot
щоб переконатися, що повернені значення відповідають тому, що ви очікували, але vapply
трохи легше (якщо більш обмежене, оскільки спеціальний код перевірки помилок може перевіряти значення в межах і т.д.). ).
Ось приклад vapply
забезпечення вашого результату таким, як очікувалося. Це паралельно з тим, над чим я просто працював під час вишкрібання PDF, де findD
б використовувався файлрегулярне вираженнядля збігу з шаблоном у необроблених текстових даних (наприклад, я мав би список, який був split
за суттю, і регулярний вираз, який відповідав би адресам у кожному об’єкті. Іноді PDF перетворювались не в порядку, і для адреси було б дві адреси сутність, яка спричинила поганий стан).
> input1 <- list( letters[1:5], letters[3:12], letters[c(5,2,4,7,1)] )
> input2 <- list( letters[1:5], letters[3:12], letters[c(2,5,4,7,15,4)] )
> findD <- function(x) x[x=="d"]
> sapply(input1, findD )
[1] "d" "d" "d"
> sapply(input2, findD )
[[1]]
[1] "d"
[[2]]
[1] "d"
[[3]]
[1] "d" "d"
> vapply(input1, findD, "" )
[1] "d" "d" "d"
> vapply(input2, findD, "" )
Error in vapply(input2, findD, "") : values must be length 1,
but FUN(X[[3]]) result is length 2
Як я кажу своїм студентам, частина того, як стати програмістом, змінює ваше мислення з "помилки дратують" на "помилки - це мій друг".
Введення нульової довжини Однією з пов’язаних точок є те, що якщо довжина введення дорівнює нулю, sapply
завжди буде повертатися порожній список, незалежно від типу вводу. Порівняйте:
sapply(1:5, identity)
sapply(integer(), identity)
vapply(1:5, identity)
vapply(integer(), identity)
З vapply
, ви гарантовано матимете певний тип виводу, тому вам не потрібно писати додаткові перевірки на введення нульової довжини.
Тести
vapply
може бути трохи швидшим, оскільки він уже знає, в якому форматі слід очікувати результатів.
input1.long <- rep(input1,10000)
library(microbenchmark)
m <- microbenchmark(
sapply(input1.long, findD ),
vapply(input1.long, findD, "" )
)
library(ggplot2)
library(taRifx)
autoplot(m)