R:Оформление кода — различия между версиями

Материал Psylab.info - энциклопедии психодиагностики
Перейти к: навигация, поиск
м (Названия функций и переменных)
м (Функция tidy.source())
 
(не показано 11 промежуточных версий этого же участника)
Строка 11: Строка 11:
 
Прежде всего, названия файлов должны быть '''осмысленными''' и понятными.
 
Прежде всего, названия файлов должны быть '''осмысленными''' и понятными.
  
Общим требования к именованию файлов является написания расширений файлов, включающего принадлежность к языку программирования R с большой буквы. Обратим внимание, что все UNIX-like операционные системы чувствительны к регистру в названиях файлов. Например: {{Inline-code|pulse-analyse.R, report.Rmw, presentation.Rmd|lang="bash"}}. Бинарный формат хранения данных имеет расширение {{Inline-code|.RData|lang="bash"}}.
+
Общим требования к именованию файлов является написания расширений файлов, включающего принадлежность к языку программирования R с большой буквы. Обратим внимание, что все UNIX-like операционные системы чувствительны к регистру в названиях файлов. Например: <code>pulse-analyse.R</code>, <code>report.Rmw</code>, <code>presentation.Rmd</code>. Бинарный формат хранения данных имеет расширение <code>.RData</code>.
  
 
Имена файлов содержат символы в нижнем регистре.
 
Имена файлов содержат символы в нижнем регистре.
Строка 21: Строка 21:
 
Существуют различные подходы к именованию функций и переменных. Но все они содержат общие рекомендации:
 
Существуют различные подходы к именованию функций и переменных. Но все они содержат общие рекомендации:
  
* Названия должны быть понятны и осмысленны: {{Inline-code|colMeans|lang="rsplus"}}, {{Inline-code|read.table|lang="rsplus"}};
+
* Названия должны быть понятны и осмысленны: <code>colMeans</code>, <code>read.table</code>;
 
* Названия не должны быть слишком длинными или слишком короткими, что могли бы затруднить их понимание или восприятие;
 
* Названия не должны быть слишком длинными или слишком короткими, что могли бы затруднить их понимание или восприятие;
 +
* Не использовать имена уже используются в R или популярных пакетах. Для проверки уже используемых имён можно использовать функции <code>find()</code> и <code>apropos()</code>;
  
 
Можно выделить несколько подходов к именованию функций и переменных:
 
Можно выделить несколько подходов к именованию функций и переменных:
  
* alllowercase (слитное написание, все символы в нижнем регистре, без разделителей). Широко используется в MATLAB. Примеры: {{Inline-code|searchpaths|lang="rsplus"}}, {{Inline-code|searchpaths|lang="rsplus"}};
+
* alllowercase (слитное написание, все символы в нижнем регистре, без разделителей). Широко используется в MATLAB. Примеры: <code>searchpaths</code>, <code>searchpaths</code>;
* period.separated (все символы в нижнем регистре с разделителями в виде точек). Используется только в R. Примеры: {{Inline-code|as.numeric|lang="rsplus"}}, {{Inline-code|read.table|lang="rsplus"}}, {{Inline-code|data.frame|lang="rsplus"}};
+
* period.separated (все символы в нижнем регистре с разделителями в виде точек). Используется только в R. Примеры: <code>as.numeric</code>, <code>read.table</code>, <code>data.frame</code>;
* underscore_separated (все символы в нижнем регистре с разделителями в виде нижних подчёркиваний). Используется дл именования переменных и функций в C++, Perl, Ruby. Примеры: {{Inline-code|package_version|lang="rsplus"}}, {{Inline-code|seq_along|lang="rsplus"}};
+
* underscore_separated (все символы в нижнем регистре с разделителями в виде нижних подчёркиваний). Используется дл именования переменных и функций в C++, Perl, Ruby. Примеры: <code>package_version</code>, <code>seq_along</code>;
* lowerCamelCase (слитное написание, первый символ в нижнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: {{Inline-code|colMeans|lang="rsplus"}}, {{Inline-code|suppressPackageStartupMessage.|lang="rsplus"}};
+
* lowerCamelCase (слитное написание, первый символ в нижнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: <code>colMeans</code>, <code>suppressPackageStartupMessage.</code>;
* UpperCamelCase (слитное написание, первый символ в верхнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: {{Inline-code|Vectorize|lang="rsplus"}}, {{Inline-code|NextMethod|lang="rsplus"}};
+
* UpperCamelCase (слитное написание, первый символ в верхнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: <code>Vectorize</code>, <code>NextMethod</code>;
  
В исходном коде R преимущественно используются стили lowerCamelCase, period.separated и underscore_separated. При этом period.separated, как уже отмечалось выше, используется в основном для создания функций для обработки S3 классов.
+
В различных руководствах приводятся разные рекомендации. Как мы уже отмечали, гораздо более важно придерживаться единого стиля при написании кода. В исходном коде R преимущественно используются стили lowerCamelCase, period.separated и underscore_separated. При этом period.separated, как уже отмечалось выше, используется в основном для создания функций для обработки S3 классов.
 
+
=== Название функций ===
+
 
+
* Не использовать имена уже используются в R или популярных пакетах. Для проверки уже используемых имён можно использовать функции {{Inline-code|find()|lang="rsplus"}} и {{Inline-code|apropos()|lang="rsplus"}};
+
* Избегать использование точек в названиях переменных, если только данные функции не предназначены для работы с S3 классами;
+
 
+
=== Название переменных ===
+
  
 
== Присвоение ==
 
== Присвоение ==
  
Для присвоения используется «<-» или «->», но не «=», который используется только для указания значения аргументов функций.
+
Для присвоения используется «<-» или «->», но не «=», который используется только для указания значений аргументов функций.
  
 
== Отступы ==
 
== Отступы ==
Строка 52: Строка 46:
  
 
Пробелы ставятся '''до''' и '''после''' математических символов и бинарных или логических операторов:
 
Пробелы ставятся '''до''' и '''после''' математических символов и бинарных или логических операторов:
* математические символы: «=», «+», «-», «*», «/»;
+
* математические символы: <tt>«=», «+», «-», «*», «/»</tt>;
* операторы присвоения: «<-», «->»
+
* операторы присвоения: <tt>«<-», «->»</tt>;
* бинарные операторы: «%in%», «%%», «%/%»;
+
* бинарные операторы: <tt>«%in%», «%%», «%/%»</tt>;
* логические операторы: «==», «!=», «&», «|», «<», «>», «<=», «>=».
+
* логические операторы: <tt>«==», «!=», «&», «|», «<», «>», «<=», «>=»</tt>.
  
 
Пробелы также ставятся '''после''' запятых.
 
Пробелы также ставятся '''после''' запятых.
  
Пробелы ставятся '''перед''' открывающейся фигурной скобкой - «{».
+
Пробелы ставятся '''перед''' открывающейся фигурной скобкой - <tt>«{»</tt>.
  
Пробелы ставятся '''перед''' открывающейся круглой скобкой - «(», за исключением объявления или вызова функции.
+
Пробелы ставятся '''перед''' открывающейся круглой скобкой - <tt>«(»</tt>, за исключением объявления или вызова функции.
  
 
Пробелы также '''не''' ставятся между круглыми скобками:
 
Пробелы также '''не''' ставятся между круглыми скобками:
  
<syntaxhighlight lang="rsplus">
+
{{r-code|code=<nowiki>if ( (x == 1) & (y == 2) )</nowiki>}}
if ( (x == 1) & (y == 2) )
+
</syntaxhighlight>
+
  
 
Более корректно:
 
Более корректно:
  
<syntaxhighlight lang="rsplus">
+
{{r-code|code=<nowiki>if ((x == 1) & (y == 2))</nowiki>}}
if ((x == 1) & (y == 2))
+
</syntaxhighlight>
+
  
 
Рекомендуется отделять пробелами оператор присвоения значений аргументов:
 
Рекомендуется отделять пробелами оператор присвоения значений аргументов:
  
<syntaxhighlight lang="rsplus">
+
{{r-code|code=<nowiki>plot(x,y, lwd=4, col=green, main="My Title")</nowiki>}}
plot(x,y, lwd=4, col=green, main="My Title")
+
</syntaxhighlight>
+
  
 
Более корректно:
 
Более корректно:
  
<syntaxhighlight lang="rsplus">
+
{{r-code|code=<nowiki>plot(x,y, lwd = 4, col = green, main = "My Title")</nowiki>}}
plot(x,y, lwd = 4, col = green, main = "My Title")
+
 
</syntaxhighlight>
+
== Функция <code>tidy.source()</code> ==
 +
 
 +
Пакет {{r-package|formatR}} содержит функцию <code>tidy.source()</code>, которая позволяет отформатировать исходный код согласно заранее определённым правилам (аргументам). Функция поддерживает ввод из буфера обмена (<code>source = "clipboard"</code>), файла (<code>source = "filename"</code>) или переменной (<code>source = varname</code>), являющейся вектором строк (character vector). Вывод результатов работы функции может быть перенаправлен в консоль (<code>output = TRUE</code>) или файл (<code>file = "filename"</code>).
 +
 
 +
В качестве настроек форматирования можно указать:
 +
 
 +
* сохранять комментарии (аргумент <code>keep.comment</code>, по умолчанию <code>TRUE</code>);
 +
* сохранять пустые строки (аргумент <code>keep.blank.line</code>, по умолчанию <code>TRUE</code>);
 +
* заменять оператор присвоения с <code>=</code> на <code><-</code> (аргумент <code>replace.assign</code>, по умолчанию <code>FALSE</code>);
 +
* ставить открывающуюся фигурную скобку (<code>{</code>) на новую строку (аргумент <code>left.brace.newline</code>, по умолчанию <code>FALSE</code>);
 +
* количество пробелов, использующихся для отступов (аргумент <code>reindent.spaces</code>. по умолчанию 4 пробела);
 +
* количество символов, при достижении которого текст переносится на новую строку (аргумент <code>idth.cutoff</code>, по умолчанию равен опции <code>width</code>).
 +
 
 +
Для демонстрации работы функции <code>tidy.source()</code> возьмём файл <code>messy.R</code>, который поставляется в составе пакета {{r-package|formatR}}. Вот его содержимое:
 +
 
 +
{{file
 +
  |filename=messy.R
 +
  |lang=r
 +
  |code=
 +
<nowiki>    # a single line of comments is preserved
 +
1+1
 +
 
 +
if(TRUE){
 +
x=1  # inline comments
 +
}else{
 +
x=2;print('Oh no... ask the right bracket to go away!')}
 +
1*3 # one space before this comment will become two!
 +
2+2+2    # 'short comments'
 +
 
 +
lm(y~x1+x2, data=data.frame(y=rnorm(100),x1=rnorm(100),x2=rnorm(100)))  ### only 'single quotes' are allowed in comments
 +
1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1  ## comments after a long line
 +
'a character string with \t in it'
 +
 
 +
## here is a long long long long long long long long long long long long long long long long long long long long comment
 +
</nowiki>
 +
}}
 +
 
 +
Результат работы функции:
 +
 
 +
{{r-code
 +
  |code=
 +
<nowiki>
 +
> library(formatR)
 +
> options(width = 80)
 +
> tidy.source(source = paste0(.libPaths()[1], "/formatR/format/messy.R"))
 +
# a single line of comments is preserved
 +
1 + 1
 +
 
 +
if (TRUE) {
 +
    x <- 1  # inline comments
 +
} else {
 +
    x <- 2
 +
    print("Oh no... ask the right bracket to go away!")
 +
}
 +
1 * 3  # one space before this comment will become two!
 +
2 + 2 + 2  # 'short comments'
 +
 
 +
lm(y ~ x1 + x2, data = data.frame(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100)))  ### only 'single quotes' are allowed in comments
 +
1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +
 +
    1 + 1  ## comments after a long line
 +
"a character string with \t in it"
 +
 
 +
## here is a long long long long long long long long long long long long long long
 +
## long long long long long long comment</nowiki>
 +
}}
  
 
== Общая логика и порядок написания скриптов ==
 
== Общая логика и порядок написания скриптов ==
Строка 92: Строка 144:
 
# Комментарий, содержащий информацию об авторе;
 
# Комментарий, содержащий информацию об авторе;
 
# Комментарий, содержащий информацию о содержании и назначении скрипта;
 
# Комментарий, содержащий информацию о содержании и назначении скрипта;
# Импорт пакетов и скриптов - вызов {{Inline-code|library()|lang="rsplus"}} и {{Inline-code|source()|lang="rsplus"}};
+
# Импорт пакетов и скриптов - вызов <code>library()</code> и <code>source()</code>;
 
# Объявления функций:
 
# Объявления функций:
 
# Выполнение основный выражений.
 
# Выполнение основный выражений.
  
 
=== Ссылки ===
 
=== Ссылки ===
 +
 
* R Style. An Rchaeological Commentary - http://cran.r-project.org/web/packages/rockchalk/vignettes/Rstyle.pdf
 
* R Style. An Rchaeological Commentary - http://cran.r-project.org/web/packages/rockchalk/vignettes/Rstyle.pdf
 
* Google's R Style Guide - http://google-styleguide.googlecode.com/svn/trunk/Rguide.xml
 
* Google's R Style Guide - http://google-styleguide.googlecode.com/svn/trunk/Rguide.xml

Текущая версия на 07:37, 16 апреля 2014

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

К сожалению, для языка R нет чётких правил оформления кода. В качестве источников таких правил обычно используется исходный код ядра R, в котором, правда, наблюдается весьма разнородные варианты оформления. Дополнительными источниками являются стандарты оформления кода, заимствованные из других языков программирования.

Одним из общих правил является необходимость придерживаться одного стиля в рамках одного проекта всего проекта.

Названия файлов

Прежде всего, названия файлов должны быть осмысленными и понятными.

Общим требования к именованию файлов является написания расширений файлов, включающего принадлежность к языку программирования R с большой буквы. Обратим внимание, что все UNIX-like операционные системы чувствительны к регистру в названиях файлов. Например: pulse-analyse.R, report.Rmw, presentation.Rmd. Бинарный формат хранения данных имеет расширение .RData.

Имена файлов содержат символы в нижнем регистре.

Для замены пробелов в названиях файлов обычно используются дефисы или нижние подчёркивания.

Названия функций и переменных

Существуют различные подходы к именованию функций и переменных. Но все они содержат общие рекомендации:

  • Названия должны быть понятны и осмысленны: colMeans, read.table;
  • Названия не должны быть слишком длинными или слишком короткими, что могли бы затруднить их понимание или восприятие;
  • Не использовать имена уже используются в R или популярных пакетах. Для проверки уже используемых имён можно использовать функции find() и apropos();

Можно выделить несколько подходов к именованию функций и переменных:

  • alllowercase (слитное написание, все символы в нижнем регистре, без разделителей). Широко используется в MATLAB. Примеры: searchpaths, searchpaths;
  • period.separated (все символы в нижнем регистре с разделителями в виде точек). Используется только в R. Примеры: as.numeric, read.table, data.frame;
  • underscore_separated (все символы в нижнем регистре с разделителями в виде нижних подчёркиваний). Используется дл именования переменных и функций в C++, Perl, Ruby. Примеры: package_version, seq_along;
  • lowerCamelCase (слитное написание, первый символ в нижнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: colMeans, suppressPackageStartupMessage.;
  • UpperCamelCase (слитное написание, первый символ в верхнем регистре, начало каждого составного слова в верхнем регистре). Используется во многих языках программирования. Примеры: Vectorize, NextMethod;

В различных руководствах приводятся разные рекомендации. Как мы уже отмечали, гораздо более важно придерживаться единого стиля при написании кода. В исходном коде R преимущественно используются стили lowerCamelCase, period.separated и underscore_separated. При этом period.separated, как уже отмечалось выше, используется в основном для создания функций для обработки S3 классов.

Присвоение

Для присвоения используется «<-» или «->», но не «=», который используется только для указания значений аргументов функций.

Отступы

Для отступов могут использоваться как пробелы, так и табуляция. В R coding standards рекомендуется использовать 4 пробела для кода и 2 пробела для документации. В Google's R Style Guide рекомендуется использоваться 2 пробела. Важно, чтобы отступы были везде одинаковыми, т.е. только пробелы или только табуляция.

Расстановка пробелов

Пробелы ставятся до и после математических символов и бинарных или логических операторов:

  • математические символы: «=», «+», «-», «*», «/»;
  • операторы присвоения: «<-», «->»;
  • бинарные операторы: «%in%», «%%», «%/%»;
  • логические операторы: «==», «!=», «&», «|», «<», «>», «<=», «>=».

Пробелы также ставятся после запятых.

Пробелы ставятся перед открывающейся фигурной скобкой - «{».

Пробелы ставятся перед открывающейся круглой скобкой - «(», за исключением объявления или вызова функции.

Пробелы также не ставятся между круглыми скобками:

КодR

<syntaxhighlight lang="r">if ( (x == 1) & (y == 2) )</syntaxhighlight>

Более корректно:

КодR

<syntaxhighlight lang="r">if ((x == 1) & (y == 2))</syntaxhighlight>

Рекомендуется отделять пробелами оператор присвоения значений аргументов:

КодR

<syntaxhighlight lang="r">plot(x,y, lwd=4, col=green, main="My Title")</syntaxhighlight>

Более корректно:

КодR

<syntaxhighlight lang="r">plot(x,y, lwd = 4, col = green, main = "My Title")</syntaxhighlight>

Функция tidy.source()

Пакет formatR содержит функцию tidy.source(), которая позволяет отформатировать исходный код согласно заранее определённым правилам (аргументам). Функция поддерживает ввод из буфера обмена (source = "clipboard"), файла (source = "filename") или переменной (source = varname), являющейся вектором строк (character vector). Вывод результатов работы функции может быть перенаправлен в консоль (output = TRUE) или файл (file = "filename").

В качестве настроек форматирования можно указать:

  • сохранять комментарии (аргумент keep.comment, по умолчанию TRUE);
  • сохранять пустые строки (аргумент keep.blank.line, по умолчанию TRUE);
  • заменять оператор присвоения с = на <- (аргумент replace.assign, по умолчанию FALSE);
  • ставить открывающуюся фигурную скобку ({) на новую строку (аргумент left.brace.newline, по умолчанию FALSE);
  • количество пробелов, использующихся для отступов (аргумент reindent.spaces. по умолчанию 4 пробела);
  • количество символов, при достижении которого текст переносится на новую строку (аргумент idth.cutoff, по умолчанию равен опции width).

Для демонстрации работы функции tidy.source() возьмём файл messy.R, который поставляется в составе пакета formatR. Вот его содержимое:

Файлmessy.R

<syntaxhighlight lang="r" enclose="pre"> # a single line of comments is preserved 1+1 if(TRUE){ x=1 # inline comments }else{ x=2;print('Oh no... ask the right bracket to go away!')} 1*3 # one space before this comment will become two! 2+2+2 # 'short comments' lm(y~x1+x2, data=data.frame(y=rnorm(100),x1=rnorm(100),x2=rnorm(100))) ### only 'single quotes' are allowed in comments 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 ## comments after a long line 'a character string with \t in it' ## here is a long long long long long long long long long long long long long long long long long long long long comment </syntaxhighlight>

Результат работы функции:

КодR

<syntaxhighlight lang="r"> > library(formatR) > options(width = 80) > tidy.source(source = paste0(.libPaths()[1], "/formatR/format/messy.R")) # a single line of comments is preserved 1 + 1 if (TRUE) { x <- 1 # inline comments } else { x <- 2 print("Oh no... ask the right bracket to go away!") } 1 * 3 # one space before this comment will become two! 2 + 2 + 2 # 'short comments' lm(y ~ x1 + x2, data = data.frame(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100))) ### only 'single quotes' are allowed in comments 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 ## comments after a long line "a character string with \t in it" ## here is a long long long long long long long long long long long long long long ## long long long long long long comment</syntaxhighlight>

Общая логика и порядок написания скриптов

  1. Комментарий, содержащий информацию о лицензии, под которой распространяется код;
  2. Комментарий, содержащий информацию об авторе;
  3. Комментарий, содержащий информацию о содержании и назначении скрипта;
  4. Импорт пакетов и скриптов - вызов library() и source();
  5. Объявления функций:
  6. Выполнение основный выражений.

Ссылки