Какие функции R не подходят для программного использования?

Некоторые функции, такие как browser, имеют смысл только при интерактивном использовании.

Широко распространено мнение, что функцию subset следует использовать только интерактивно.

Точно так же sapply не подходит для программного использования, поскольку не упрощает результат для входных данных нулевой длины.

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

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

Существуют и другие функции, такие как file.choose и readline, которые требуют интерактивности, но их можно включать в пакеты, поскольку конечное использование будет интерактивным. Меня это не слишком волнует для этого варианта использования, но не стесняйтесь добавлять их в список.

Какие функции я пропустил?


person Richie Cotton    schedule 27.04.2014    source источник
comment
imho attach ни в коем случае нельзя использовать, тем более программно. И, конечно же, View, edit и друзья. Я не уверен, что согласен с sapply.   -  person Roland    schedule 27.04.2014
comment
@Roland Согласен с attach. Я считаю, что sapply вызывает слишком много неясных ошибок из-за ввода нулевой длины. Например, sapply(x, length) возвращает целочисленный вектор, если только x не имеет длины 0, и в этом случае вы получите список. Если вы знаете, что размер вывода постоянен, используйте vapply, иначе используйте lapply.   -  person Richie Cotton    schedule 27.04.2014
comment
Кстати, мой мотив для этого вопроса заключается в том, что я продолжаю случайно оставлять вызовы browser в своем коде, что выглядит глупо, если вы зарегистрируете его в репозитории.   -  person Richie Cotton    schedule 27.04.2014
comment
Возможно, вам также следует предостеречь от cat. Часто вместо этого следует использовать message.   -  person Roland    schedule 27.04.2014
comment
sapply в любом случае является частным случаем lapply   -  person rawr    schedule 27.04.2014
comment
Это может быть немного радикально. Проблема с такими функциями, как subset, при использовании в программировании заключается в том, что они используют нестандартную оценку своих аргументов. Это потенциальная проблема только в том случае, если те аргументы, которые оцениваются с использованием нестандартной оценки, являются переданными переменными. Такие функции по-прежнему можно безопасно использовать в функциях, если аргументы, подлежащие нестандартной оценке, передаются в виде константных выражений. Например, subset(data, id == 1) не будет проблемой в функции.   -  person G. Grothendieck    schedule 27.04.2014
comment
@ G.Grothendieck Хорошо, subset не очень опасно. Одна вещь, которая была бы удивительной для R, — это автоматическая проверка и исправление кода MATLAB. bit.ly/1iqehBz Идея, каких функций следует избегать, — это то, что я могу построить в день? эквивалент.   -  person Richie Cotton    schedule 27.04.2014
comment
Это почти само собой разумеется, но в случае, если какие-либо новые пользователи R просматривают этот ответ, избегайте циклов for, поскольку они очень медленные.   -  person statsRus    schedule 27.04.2014
comment
@Roland Так уж получилось, что у меня есть случай, когда attach required (но стоит отметить, что это вызывается только тогда, когда пользователь находится либо в интерактивном режиме, либо передает параметр, который в любом случае не рекомендуется).   -  person Konrad Rudolph    schedule 27.04.2014
comment
sapply подходит при использовании simplify=FALSE. Чтобы получить тот же результат, что и sapply(letters[1:3], "(", simplify=FALSE) с lapply, вы должны быть избыточными setNames(lapply(letters[1:3], "("), letters[1:3])   -  person GSee    schedule 27.04.2014


Ответы (2)


(Не стесняйтесь редактировать.)

Со следующими функциями следует обращаться осторожно (что не обязательно означает, что они не подходят для программирования):

  • Функции, выходные данные которых не имеют согласованного выходного класса в зависимости от входных данных: sapply, mapply (по умолчанию)

  • Функции, внутреннее поведение которых различается в зависимости от длины ввода: sample, seq

  • Функции, которые оценивают некоторые из своих аргументов в средах: $, subset, with, within, transform.

  • Функции, которые противоречат обычному использованию среды: attach, detach, assign, <<-

  • Функции, допускающие частичное совпадение: $

  • Функции, которые имеют смысл только при интерактивном использовании: browser, recover, debug, debugonce, edit, fix, menu, select.list

  • Функции, которые могут представлять угрозу (вирус) при использовании с пользовательским вводом: source, eval(parse(text=...)), system.

Также в какой-то степени каждая функция генерирует предупреждения, а не ошибки. Я рекомендую использовать options(warn = 2), чтобы превратить все предупреждения в ошибки в программном приложении. Конкретные случаи могут быть разрешены с помощью suppressWarnings или try.

person flodel    schedule 27.04.2014
comment
Интересно, что поскольку частичное совпадение имен столбцов data.frame в R 3.1.0 выдает предупреждение, см. НОВОСТИ. - person gagolews; 27.04.2014
comment
...но не списки (например, cars$d против as.list(cars)$d), вздох. - person flodel; 27.04.2014

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

badLines <- function(func) {
    bad <- c("sapply", "subset", "attach")
    regex <- paste0("\\b", bad, "\\b")
    result <- sort(unlist(sapply(regex, FUN = grep, body(func), simplify = FALSE)))
    setNames(result, gsub("\\b", "", names(result), fixed = TRUE))
}
badLines(badLines)

## sapply1  subset  attach sapply2 
##       2       2       2       4 
person G. Grothendieck    schedule 27.04.2014
comment
Некоторые люди могут найти пакет lint полезным для такого рода проверки кода. Он достаточно гибкий, чтобы вы могли определять свои собственные правила. Однако у него довольно крутая кривая обучения и плохая документация/поддержка. - person flodel; 27.04.2014
comment
@flodel Хороший совет по поводу пакета lint. Я только что попробовал lint(dir("mypackage/R", full.names = TRUE)), и он выдал кучу вещей, которых я раньше не замечал. - person Richie Cotton; 28.04.2014