บล็อกเพื่อแลกเปลี่ยนเรียนรู้ สำหรับนักพัฒนาฟังก์ชันสำหรับ R ในประเทศไทย
สนับสนุนโดย สำนักงานกองทุนสนับสนุนการวิจัย (สกว)

10 พฤษภาคม 2548

การเขียนแฟ้มความช่วยเหลือในรูปแบบ R document

หัวข้อนี้จะกล่าวถึงการเขียนแฟ้มความช่วยเหลือในรูปแบบ R document (Rd) ซึ่งเป็นรูปแบบที่แนะนำให้ใช้ในการเขียนแฟ้มความช่วยเหลือสำหรับ function ต่างๆ ใน R เนื่องจากในขณะ build นั้นโปรแกรม R CMD check (บน Linux และ Macintosh) หรือ Rcmd check (บน Windows) จะแปลงให้เป็นรูปแบบมาตรฐานที่ใช้ได้สำหรับทุก platform โดยอัตโนมัติ ได้แก่ รูปแบบ text และ รูปแบบ html ที่อ่านได้ด้วยโปรแกรม web browser เช่น Internet Explorer หรือ FireFox และรูปแบบอื่นที่เหมาะสมกับ platform นั้นๆ เช่น chtml บน Windows หรือรูปแบบ dvi บน Linux

เนื้อหาต่อไปนี้สรุปมาจากคู่มือ Writing R Extensions นั่นเอง แต่ได้สรุปให้ง่ายขึ้น และเพิ่มเติมตัวอย่างให้เห็นการทำงานที่ชัดเจนยิ่งขึ้น ผู้สนใจอาจอ่านรายละเอียดเพิ่มเติมได้ใน Writing R Extensions

การเขียนแฟ้ม Rd จะเขียนในรูปแบบคำสั่ง ไม่ใช่เขียนเป็นข้อความโดยตรง แต่คำสั่งมีไม่มากนัก และมีรูปแบบการเขียนที่แน่นอน จึงสามารถทำความเข้าใจและจดจำได้ไม่ยากนัก คำสั่ง markup พื้นฐานมีดังนี้

\name{name}
\alias{topic}
\title{Title}
\description{}
\usage{fun(arg1, arg2, …)}
\arguments{}
\details{}
\value{}
\references{}
\note{}
\author{}
\seealso{}
\examples{}
\keyword{key}

ซึ่งลำดับดังที่เห็นจะเป็นลำดับที่เห็นได้ในข้อความช่วยเหลือเมื่อเรียกคำสั่ง help ใน R นั่นเอง ดังนั้นการเขียนแฟ้ม Rd จึงต้องเขียนคำสั่งตามลำดับนี้เสมอ

สังเกตว่าคำสั่งในรูปแบบ Rd จะขึ้นต้นด้วยเครื่องหมาย backslash (\) เสมอ และตามด้วยข้อความที่ต้องการให้นำมาแสดงอยู่ภายในเครื่องหมายวงเล็บปีกกา { } ขณะที่ build นั้น R CMD check จะจัดการกับข้อความภายในนั้นอย่างเหมาะสม เช่นข้อความช่วยเหลือชนิด text ของ pack ใน package epican จะเขียนดังนี้

\name{pack}
\alias{pack}
\title{Pack a Dataset}
\description{
Pack a case-by-case data frame into a compact format with frequencies and means.
}

\usage{
pack(data, select, FUN)
}

\arguments{
\item{data}{a data frame.}
\item{select}{a vector of variable in the data frame by which a compact
dataset is formed.}

\item{FUN}{a scalar function to compute the summary statistics which can be
applied to all data subsets.}

}

\details{
The function packs a case-by-case data frame into a compact one. A list of vector
to be the keys for aggregation of the data must be specified in 'select'. If 'FUN'
is not specified, frequency is assumed and a 'freq' column is added as the last
column in the resulting data frame. If 'FUN' is specified, the function is applied
to all non-factor columns and the results will be displayed for each combination
of 'select' categories.


At the moment, mean is the only function that can be specified in 'FUN' as the
example below.

}

\value{
A compact data frame containing frequencies or functions defined in 'FUN'.
}

\seealso{
\code{\link{aggregate}}
}

\examples{
data(cca)
cca1 <- pack(cca,c(ovab,alcohol))
cca2 <- pack(cca,c(ovab,alcohol),FUN=mean)
cca1; cca2
}

\keyword{datagen}

ข้อความช่วยเหลือชนิด text ของ pack เมื่อเรียกด้วย function help ใน R จะออกมาเป็นดังนี้

pack                 package:epican                 R Documentation

Pack a Dataset

Description:
Pack a case-by-case data frame into a compact format with
frequencies and means.

Usage:
pack(data, select, FUN)

Arguments:
data: a data frame.

select: a vector of variable in the data frame by which a compact
dataset is formed.

FUN: a scalar function to compute the summary statistics which can
be applied to all data subsets.

Details:
The function packs a case-by-case data frame into a compact one. A
list of vector to be the keys for aggregation of the data must be
specified in 'select'. If 'FUN' is not specified, frequency is
assumed and a 'freq' column is added as the last column in the
resulting data frame. If 'FUN' is specified, the function is
applied to all non-factor columns and the results will be
displayed for each combination of 'select' categories.

At the moment, mean is the only function that can be specified in
'FUN' as the example below.

Value:
A compact data frame containing frequencies or functions defined
in 'FUN'.

See Also:
'aggregate'

Examples:
data(cca)
cca1 <- pack(cca,c(ovab,alcohol))
cca2 <- pack(cca,c(ovab,alcohol),FUN=mean)
cca1; cca2

จะเห็นว่าในบางกรณี เช่น \title จะถูกแสดงโดยไม่มีหัวข้อนำหน้า แต่ในกรณีของ \description และ \usage จะถูกแสดงโดยมีหัวข้อ Description: และ Usage: นำ เป็นต้น รายละเอียดในการเขียนแต่ละคำสั่งมีดังต่อไปนี้

ที่น่าสนใจคือเราอาจเขียนแฟ้มความช่วยเหลือเป็นภาษาไทยได้ด้วย ซึ่ง R CMD check จะ build ให้เป็นภาษาไทย แต่อย่างไรก็ตามเนื่องจากในขณะนี้ help window ยังไม่สามารถแสดงเป็นภาษาไทยได้ หากต้องการข้อความช่วยเหลือเป็นภาษาไทย จึงต้องใช้รูปแบบ html หรือ chtml เท่านั้น ตัวอย่างแฟ้มความช่วยเหลือภาษาไทยของ pack เป็นดังนี้

\name{pack}
\alias{pack}
\title{ยุบชุดข้อมูล}
\description{
ยุบชุดข้อมูลแจกแจงรายบุคคลให้เป็นรูปแบบยุบตามความถี่หรือค่าเฉลี่ย
}

\usage{
pack(data, select, FUN)
}

\arguments{
\item{data}{กรอบข้อมูล}
\item{select}{ลิสต์ของเวกเตอร์ที่ต้องการใช้สร้างกรอบข้อมูลที่ยุบแล้ว}
\item{FUN}{ฟังก์ชันที่จะคำนวณค่าสถิติสรุปของข้อมูลที่ต้องการทำงานกับทุกตัวแปรในกรอบข้อมูล}
}

\details{
คำสั่งนี้ยุบกรอบข้อมูลแบบแจกแจงรายบุคคลให้เป็นแบบสรุปย่อ ระบุลิสต์ของเวกเตอร์ที่จะใช้เป็นตัวแปรหลัก
ในการยุบย่อข้อมูลไว้ใน
'select' ถ้าไม่ระบุ 'FUN' คำสั่งจะถือว่าต้องการสรุปย่อความถี่ และสดมภ์ชื่อ
'freq'
จะถูกสร้างต่อท้ายกรอบข้อมูลที่สร้างขึ้นใหม่ หากระบุ 'FUN' คำสั่งจะทำฟังก์ชันนี้กับทุกสดมภ์ที่
ไม่ใช่แฟกเตอร์และแสดงค่าสำหรับแต่ละชุดของ
'select' ในกรอบข้อมูลที่สร้างขึ้น

ในขณะนี้ mean เป็นฟังก์ชันเดียวที่สามารถใช้ได้กับ 'FUN' ตามตัวอย่างข้างล่าง
}

\value{
กรอบข้อมูลในรูปแบบสรุปย่อแสดงความถี่หรือค่าที่ได้จากฟังก์ชันที่ระบุใน 'FUN'
}

\seealso{
\code{\link{aggregate}}
}

\examples{
data(cca)
cca1 <- pack(cca,c(ovab,alcohol))
cca2 <- pack(cca,c(ovab,alcohol),FUN=mean)
cca1; cca2
}

\keyword{datagen}

นั่นคือเป็นการแปลข้อความบางส่วนจากภาษาอังกฤษเป็นภาษาไทยนั่นเอง แต่ด้วยข้อจำกัดของการแสดงภาษาไทยใน help window ของ R หากต้องการเขียนข้อความช่วยเหลือภาษาไทยบน Windows จึงแนะนำวิธีใดวิธีหนึ่งดังนี้ คือ

  1. เขียนแฟ้มความช่วยเหลือเป็นภาษาอังกฤษด้วย โดย build แยกกันในแต่ละภาษาแล้ว จึงค่อยนำ help ในรูปแบบ text ที่เป็นภาษาอังกฤษมาแทนที่ภาษาไทย เพื่อให้เวลาเรียก help ตามปกติจะได้ข้อความช่วยเหลือเป็นภาษาอังกฤษ และเมื่อเรียก help ด้วยตัวเลือก html=TRUE จึงแสดงเป็นภาษาไทย
  2. แก้ไขแฟ้ม Rprofile ในโฟลเดอร์ R_HOME/etc โดยเอาเครื่องหมาย # หน้า options(htmlhelp=TRUE) หรือ options(chmhelp=TRUE) ออก ซึ่งเป็นการกำหนดตั้งแต่ต้นเริ่มเรียกโปรแกรม R ให้เลือกวิธีแสดงข้อความช่วยเหลือเป็น html หรือ chtml โดยไม่ให้แสดงเป็น text นั่นเอง

ในกรณีของคอมพิวเตอร์ระบบ Macintosh นั้นไม่ต้องเปลี่ยนแปลงอย่างใดทั้งสิ้น เนื่องจากโปรแกรมจะใช้รูปแบบ html เป็นปกติโดยไม่ใช้รูปแบบ text อยู่แล้ว ส่วนบนระบบ Linux นั้น ใช้วิธีการเรียกข้อความช่วยเหลือโดยระบุตัวเลือก html=TRUE (หรือเขียนย่อว่า h=T ก็ได้) เช่น help(pack, h=T)

ต่อไปนี้เป็นรายละเอียดของแต่ละคำสั่ง

\name{name}

name โดยปกติแล้วก็จะเป็นชื่อของแฟ้ม Rd นั้นเอง และเป็นชื่อของวัตถุ ซึ่งในที่นี้คือ function ใน package นั่นเอง วัตถุใน package นั้นจะต้องไม่มีชื่อซ้ำกัน นั่นคือจะต้องไม่ตั้งชื่อวัตถุอื่นใดซ้ำกับชื่อ function ใน package เดียวกัน ดูตัวอย่างในกรณีของคำสั่ง pack ใน package:epican ที่แสดงข้างต้น

\alias{topic}

\alias ระบุทุกๆ หัวข้อที่แฟ้มนั้นให้คำอธิบายอยู่ ข้อมูลนี้จะรวมกันอยู่ในฐานข้อมูล index ในการค้นหาด้วยระบบความช่วยเหลือทั้งในรูปแบบ text และ html

โดยปกติแล้ว \alias มักเป็นชื่อของ function นั้นเองที่ระบุอยู่ใน \name แต่ก็อาจมี \alias หลายๆ อันภายใต้ \name อันเดียวได้ มีบ่อยครั้งที่เราต้องการเขียนคำอธิบายหลายๆ วัตถุใน R ด้วยแฟ้มเดียว ตัวอย่างเช่น แฟ้ม Normal.Rd ใน package:stats ที่อธิบายเกี่ยวกับ density distribution function, quantile function และการสร้างตัวเลขสุ่มตามการกระจายแบบปกติ เริ่มต้นแฟ้มด้วยชุดคำสั่งต่อไปนี้

            \name{Normal}
\alias{dnorm}
\alias{pnorm}
\alias{rnorm}

นอกจากนี้เราอาจตั้งชื่อ function หนึ่งด้วยหลายชื่อก็ได้ เช่นใน package:epican นั้น to.numeric กับ to.vector ทำงานเช่นเดียวกัน แต่ตั้งชื่อต่างกันเพียงเพื่อสื่อความหมายถึงการเปลี่ยนแปลงที่ต่างกันเล็กน้อย โดยที่ to.numeric สื่อถึงการเปลี่ยนจากตัวอักษรเป็นตัวเลข ขณะที่ to.vector สื่อถึงการเปลี่ยนแฟกเตอร์เป็นเวกเตอร์ ซึ่งทั้งสองกรณีก็ทำงานเช่นเดียวกัน ดังในกรณีนี้ใช้แฟ้มอธิบายร่วมกันเพียงแฟ้มเดียวคือ to.numeric.Rd ซึ่งขึ้นต้นด้วย

            \name{to.numeric}
\alias{to.numeric}
\alias{to.vector}
\alias{to.num}
\alias{to.vec}

สังเกตว่าเราอาจย่อชื่อลงได้ด้วย และก็ไม่จำเป็นต้องมีแฟ้มอธิบายสำหรับชื่อย่อนั้นแยกต่างหากแต่อย่างใด แต่ทำโดยระบุชื่อย่อเหล่านั้นเป็น alias ในแฟ้มเดียวกันนี้

เห็นได้ว่า \name ไม่จำเป็นต้องเป็นชื่อของหัวข้อความช่วยเหลือเสมอไป นั่นคือใน R console เราอาจเรียก help(to.numeric) หรือ help(to.vector) หรือแม้แต่ help(to.num) หรือ help(to.vec) R จะเรียกแฟ้มความช่วยเหลือเดียวกัน คือแฟ้ม to.numeric.Rd

\title{Title}

ข้อมูลหัวข้อของแฟ้ม Rd ถ้าเขียนในภาษาอังกฤษควรขึ้นต้นคำด้วยตัวใหญ่ ไม่ต้องใส่จุดที่ตอนท้าย และห้ามใส่ markup ใดๆ เช่น html markup ต่างๆ เพราะจำทำให้ R ค้นหาคำหลักผิดพลาด

\description{}

คำอธิบายสั้นๆ ว่า function นั้นทำอะไร ไม่เกินหนึ่งย่อหน้า (ถ้าเขียนคำอธิบายได้ยาวเกินไปโดยย่อลงไม่ได้ แสดงว่าน่าจะพยายามเขียนข้อความช่วยเหลือมากเกินไป หลายเรื่องจะนำไปเขียนอธิบายได้ภายใต้หัวข้อ \details

\usage{fun(arg1, arg2, …)}

กลุ่มของบรรทัดที่สรุปวิธีใช้ function และตัวแปรที่อธิบายในแฟ้มนั่นเอง ข้อความในส่วนนี้จะแสดงด้วยฟอนต์ตัวพิมพ์ดีดตรงตามที่เขียน (ไม่ว่าจะเป็นการขึ้นบรรทัดใหม่ ย่อหน้า หรือเว้นวรรค)

ข้อมูลการใช้ที่ระบุควรตรงกับที่เขียนระบุในการกำหนด function นั้นในแฟ้ม .R ดังตัวอย่างของ pack ข้างต้น ข้อความระบุวิธีใช้งาน pack

    pack(data, select, FUN)

ต้องตรงกับวิธีการกำหนด function ที่เขียนไว้ในแฟ้ม .R ซึ่งเขียนในรูป

           pack <- function (data, select, FUN)
{

}

เพราะในระหว่างการ build นั้น R CMD check จะตรวจสอบด้วยว่าตรงกันหรือไม่ หากไม่ตรงกันจะแสดงข้อความเตือนขึ้น ถ้าหากข้อความที่ระบุไม่ตรงกัน เช่น function cc มีวิธีการรับข้อมูลเข้าหลายวิธี แต่ในการกำหนด function นั้นได้เขียน argument ต่างๆ ต่อเนื่องกันดังนี้

           cc <- function (data, case, control, expose, table, 
a, b, c, d, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))

แต่ในการใช้งานจริง เราอาจแบ่งวิธีการเรียกใช้งานตามข้อมูลที่ส่งผ่านให้กับ function ได้ดังนี้

           cc(table, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))
cc(data, case, expose, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))
cc(a, b, c, d, outcome=get.ec.option("outcome"), frame=
get.ec.option("frame"))

คืออาจรับ argument ตัวแรกเป็น table, data frame หรือ ตัวเลข ก็ได้ กรณีเช่นนี้ R CMD check จะตรวจพบว่าวิธีการออกคำสั่งสำหรับ cc ไม่ตรงกับที่กำหนด เราสามารถใช้คำสั่ง \synopsis เพื่อคลุมวิธีการที่ตรงกับที่กำหนดในแฟ้ม .R ไว้ก่อน แล้วจึงตามด้วย \usage ที่บอกวิธีการเรียกใช้งานทั้งสามแบบ ดังนี้

           \synopsis{
cc <- function (data, case, control, expose, table,
a, b, c, d, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))
}

\usage{
cc(table, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))
cc(data, case, expose, outcome=get.ec.option("outcome"),
frame=get.ec.option("frame"))
cc(a, b, c, d, outcome=get.ec.option("outcome"), frame=
get.ec.option("frame"))
}

\arguments{}

คำอธิบาย argument แต่ละตัวของ function นั้น โดยระบุแต่ละ argument ในรูปแบบ

           \item{arg_i}{Description of arg_i}

อาจเขียนข้อความอื่นๆ ก่อนหรือหลังกลุ่มของ \item เหล่านี้ก็ได้

\details{}

รายละเอียดของการทำงานหรือวิธีใช้ function โดยพิสดารเพิ่มเติมจากข้อมูลพื้นฐานที่เขียนไว้ใน \description

\value{}

คำอธิบายค่าส่งกลับของ function ถ้าค่าส่งกลับเป็นลิสต์ที่ประกอบด้วยค่าต่างๆ จำนวนมาก อาจเขียนในรูป \item{comp_i}{Description of comp_i} สำหรับแต่ละค่าที่ส่งกลับในลิสต์นั้น อาจเขียนข้อความอธิบายอื่นๆ ไว้หน้าลิสต์นั้นก็ได้

\references{}

เป็นส่วนของการอ้างอิงบทความวิชาการ เช่นบทความที่มาของวิธีการคำนวณของ function นั้น ถ้าหากมีการอ้างอิงไปสู่เว็บ ให้ใช้ \url{} โดยใส่ url ที่เชื่อมโยงไปยังเว็บนั้นในรูปของ http://www.xxx.xxx

\note{}

ใช้สำหรับการทำหมายเหตุพิเศษที่ต้องการสื่อ ตัวอย่างเช่นใน pie.Rd ระบุหมายเหตุไว้ดังนี้

            \note{
Pie charts are a very bad way of displaying information.
The eye is good at judging linear measures and bad at
judging relative areas.
...
}

\author{}

ข้อมูลเกี่ยวกับผู้เขียนของแฟ้ม Rd นั้น หากต้องการใส่ที่อยู่ email ให้ใส่ไว้ภายใน \email{} โดยไม่ต้องใส่สัญลักษณ์อื่นๆ เช่น () หรือ <> หรืออาจใช้ \url{} ไปยังเว็บไซต์ของผู้เขียนก็ได้

\seealso{}

ชี้ไปที่วัตถุ R ที่สัมพันธ์กับ function นั้นโดยใช้ \code{\link{…}} (\code เป็นการระบุชื่อวัตถุที่จะเชื่อมโยงไปถึง และ \link สร้าง hyperlink ไปยังวัตถุนั้นหากรูปแบบของแฟ้มที่สร้างขึ้นในการ build นั้นสนับสนุนการทำงาน ตัวอย่างเช่นในกรณีของ pack ข้างต้น คำสั่งที่สัมพันธ์กันคือคำสั่ง aggregate ที่อยู่ใน package:stats ดังนั้นจึงเขียนเป็น \code{\link{aggregate}} ในขณะ build นั้น R CMD check จะค้นหาว่าคำสั่ง aggregate อยู่ใน package ใดให้เอง ดังนั้นจึงไม่ต้องระบุเส้นทางค้นหาของ aggregate ถ้า function ที่ต้องการเชื่อมโยงอยู่ใน package ที่ไม่ใช่ package มาตรฐาน ก็เป็นไปได้ที่จะหาไม่พบ ในกรณีเช่นนี้หากยังต้องการเชื่อมโยงไปยังคำสั่งนั้นจริงๆ ก็ต้องไปเพิ่ม link ในแฟ้ม html หลังการ build แล้ว

\examples{}

ตัวอย่างแสดงวิธีการใช้งาน function นั้น ข้อความเหล่านี้จะแสดงด้วยฟอนต์พิมพ์ดีด ซึ่งจะมีความกว้างของตัวอักษรและช่องว่างคงที่เท่ากันทุกตัวอักษร

ตัวอย่างไม่ได้มีประโยชน์แต่เฉพาะสำหรับการแสดงตัวอย่างเท่านั้น แต่ยังใช้สำหรับการทดสอบบรรทัดคำสั่งเพื่อตรวจสอบว่า function ทำงานได้ถูกต้องหรือไม่ โดยปกติข้อความภายใน \examples{} จะถูกแสดงในหน้าข้อความช่วยเหลือ และจะถูกทำงานด้วย R CMD check ในระหว่างการ build ด้วย สามารถใช้คำสั่ง \dontshow{} เพื่อให้ R CMD check ทดสอบบรรทัดคำสั่งที่ไม่ต้องการแสดงในหน้าข้อความช่วยเหลือ แต่จะทำงานกับคำสั่ง example() ด้วยก็ได้ (อาจใช้คำสั่ง \testonly แทนก็ได้)

ตัวอย่างเช่น

    x <- runif(10)       # Shown and run.
\dontrun{plot(x)} # Only shown.

\dontshow{log(x)} # Only run.
ดังนั้นบรรทัดตัวอย่างที่ไม่ได้อยู่ภายใต้ \dontrun ต้องทำงานได้จริง และนอกจากนั้น ไม่ควรใช้สิ่งที่เป็นลักษณะจำเพาะสำหรับคอมพิวเตอร์ระบบใดระบบหนึ่งหรือต้องการความสามารถพิเศษ (เช่นการเข้า internet หรือเขียนข้อมูลลงในไดเรกตอรี่ที่จำเพาะ ซึ่งอาจไม่มีในทุกเครื่องทุกระบบ)

ข้อมูลที่ต้องการสำหรับการสร้างให้ตัวอย่างทำงานได้อาจใช้วิธีสร้างจากตัวเลขสุ่ม (เช่นใช้ x <- rnorm(100)) หรือใช้ชุดข้อมูลมาตรฐานที่เรียกดูได้จาก data() หรือใส่ชุดข้อมูลของ package นั้นเองไว้ในโฟลเดอร์ R_HOME/library/package/data

\keyword{key}

\keyword แต่ละคำควรระบุคำหลักมาตรฐาน (ตามรายการในแฟ้ม R_HOME/doc/KEYWORDS.db) ต้องมี \keyword อย่างน้อยหนึ่งคำ หรือมากกว่าหนึ่งก็ได้ หาก function นั้นเกี่ยวข้องกับหัวข้อหลายหัวข้อ

สนับสนุนโดย สำนักงานกองทุนสนับสนุนการวิจัย (สกว)
Comments: แสดงความคิดเห็น

<< Home

This page is powered by Blogger. Isn't yours?