สร้างเอกสารภาษาไทย กับ RMarkdown

ถ้าจะสร้างเอกสารที่เป็น pdf ด้วย rmarkdown (จริงๆแล้วก็ต้องบอกว่า Knit) ใน RStudio ก็ต้องมี latex ติดตั้งลงบนเครื่องก่อน สำหรับท่านใดที่ตัดสินใจว่าจะลงผมแนะนำว่าให้ใช้ texlive ครับ และเพื่อตัดปัญหาว่าจะมีปัญหาเรื่อง package ต่างๆของ latex ผมแนะนำว่าก็ลงแบบทุกอย่างเลยแล้วกันครับ กินเนื้อที่ประมาณ 3 GB ครับ อีกอย่างจากประสบการณ์เราก็ไม่ค่อยอัพเดท latex กันบ่อยอยู่แล้ว แต่ถ้าคิดว่าเอาแค่เล็กๆก็พอ งั้นผมขอแนะนำ tinytex แล้วกันครับ วิธีติดตั้งก็ง่ายมาก ตามนี้เลยครับ

install.packages('tinytex')
tinytex::install_tinytex() 

ผมใช้ rmarkdown สร้างเอกสารเป็น pdf อยู่บ่อยครั้งแต่ส่วนมากจะเป็นภาษาอังกฤษก็มีช่วงอาทิตย์ที่ผ่านมานี้ต้องทำเป็นภาษาไทยด้วย ก็เลยอยากแชร์อะไรบ้างครับ

code หลักๆ สำหรับให้ rmarkdown  มันสร้างภาษาไทยเป็น pdf ได้ก็เพียง load package ที่จำเป็นสำหรับภาษาไทยใน latex ครับ โดยผมแนะนำว่าเพื่อความง่ายก็ขอให้เข้ารหัสสำหรับเอกสารหรือไฟล์ .Rmd เป็นแบบ Unicode หรือ UTF-8 ครับและก็ใช้ xelatex เป็นตัวโปรแกรมหลักสำหรับ latex ครับ เพราะมันใช้ได้ดีกับภาษาไทยและก็ไม่ต้องกังวลเรื่องการตัดคำครับเพราะมันสามารถทำได้กับภาษาไทยเราครับ ตัวอย่าง code อยู่ด้านล่างนี้ครับ หลักก็มีแค่ส่วนของ head-includes:

---
title: "ทดสอบ" 
header-includes:
  - \usepackage{xunicode} 
  - \usepackage{xltxtra}
  - \defaultfontfeatures{Scale=MatchLowercase} 
  - \setmainfont[Scale=1.0]{Angsana New} 
  - \XeTeXlinebreaklocale "th"
  - \XeTeXlinebreakskip = 0pt plus 1pt 
output: 
   pdf_document: 
     latex_engine: xelatex
---

## R Markdown ภาษาไทย
อ ะ ไ ร สั ก อ ย่ า ง

มันต้องมีอะไรสักอย่างในจักรวาลนี้

ที่พลัดหลงไปจากมิติกาลเวลา

อะไรสักอย่างที่โคลัมบัสและยูลิซีสตกสำรวจ

อะไรสักอย่างที่นักดาราศาสตร์กรีกและอาหรับมิได้ค้นพบ

อะไรสักอย่างที่ศาสดาของโลกลืมเทศนาสั่งสอน

อะไรสักอย่างที่ขาดหายไประหว่างหลุมดำ

..

```{r cars}
summary(cars)
```

ผลลัพท์ที่ได้ก็ประมาณนี้ครับ

ส่วนใครที่ต้องการสร้างเอกสารแบบแปลกๆสวยๆ ผมอยากแนะนำให้ศึกษา latex เพิ่มครับ แล้วจะรู้ว่าใช้ rmarkdown สร้างเอกสารlatex สะดวกจริงๆ

###

มีคนถามมาว่าในกรณีที่ใช้ rmarkdown สร้างเอกสาร html ที่ chunk ของคำสั่ง r มีการ return ค่าที่เป็นภาษาไทย อย่างตัวอย่างด้านล่างนี้มันไม่มีข้อความอะไรออกมาเลย จะทำอย่างไรถึงแม้จะใช้ Sys.setlocate(locale=”Thai”) หรือ rmarkdown::render(“file.Rmd”,enconding = “UTF-8”) แล้วก็ตาม (กรณีใช้ R ใน Windows)

วิธีที่พอจะช่วยแก้ปัญหานี้ได้บ้างระหว่างรอการแก้จากผู้พัฒนาโดยตรงที่ผมแนะนำก็คือว่าแทนที่จะ ให้มัน return ภาษาไทยออกมา ก็ให้มัน return เป็นภาษาอังกฤษ แล้วค่อยแทนที่ภาษาอังกฤษนั้นด้วยภาษาไทยที่ต้องการในไฟล์ html ที่ถูกสร้างขึ้นมาโดยตรงลองดูตัวอย่างด้านล่างนี้ครับ

ในตัวอย่างนี้ข้อความที่จะแทนที่เป็นภาษาไทยถูกเก็บไว้อีกไฟล์ (“txt4replace.R”)

library(rmarkdown)
library(stringr)

writeoutput <- function(msg,filename) {
 con <- file(filename, "w")
 tryCatch({
 cat(iconv(msg, to="UTF-8"), file=con, sep="\n")
 },
 finally = {
 close(con)
 })
}

ReplaceHTML <- function(filename,outfile) {
 htmlcode <- readLines(filename, encoding = "UTF-8")
 #read TH txt
 source("txt4replace.R")
 newhtmlcode <- str_replace_all(htmlcode,txt4replace ) 
 writeoutput(msg = newhtmlcode,filename = outfile)
}


#generate html
render("myfile.Rmd")

#replace TH txt
suppressWarnings(ReplaceHTML("myfile.html","new_myfile.html"))
browseURL("new_myfile.html")

ตัวอย่างไฟล์ "txt4replace.R"

THtext <- c("ทดสอบ","โรงเรียน","เที่ยว")
Encoding(THtext) <- "UTF-8"
txt4replace<-c("Xtxt1" = THtext[1],
 "Xtxt2" = THtext[2],
 "Xtxt3" = THtext[3])

หรือจะใช้วิธีบังคับให้มันใช้ UTF-8 ตั้งแต่ตอน render เลยก็ได้เช่น

```{r}
enc <- function(txt,...) iconv(txt, to="UTF-8")
```
```{r, echo=FALSE, results='asis', render= enc}
fn ที่ return ภาษาไทย
```

maemod (แม่มด)

ผมเขียน R package ชื่อ maemod สำหรับช่วยให้คนเพิ่งเริ่มเรียนรู้ใช้งาน R และอยากจะแก้สมการเชิงอนุพันธ์เบื้องต้น (ordinary differential equation: ode) ใน R ให้ทำได้ง่ายขึ้นครับ โดยที่ผู้ใช้งานก็เพียงเขียนสมการ ODE (ในรูปแบบคำสั่งของ R), ค่าของตัวแปรพารามิเตอร์ และค่าเริ่มต้นต่าง ๆ ของสมการ ตามตัวอย่างนี้ครับ
1. สร้างไฟล์สมมุติชื่อ test.txt ที่มีสมการตามนี้ครับ

!Equations
 dY1<-Y2
 dY2<-a*sin(Y1)+sin(t)
 
!Parameters
 a= -1.0
 
!Inits
 Y1=0,Y2=0
 
!Outputs
 c(dY1,dY2)
 
!ExtraFunctions

!Plots
!MAEMOD_End

โดยที่บรรทัดที่อยู่ถัดจาก !Equations คือสมการ ode, !Parameters คือค่าของตัวแปรต่าง ๆ, !Inits ค่าเริ่มต้นของแต่ล่ะสมการ ode, !Outputs คือlistของoutputที่ต้องการโดยที่คอลัมน์แรกซึ่งคือค่าของเวลาจะถูกเพิ่มเข้าไปอัตโนมัติเสมอ, !ExtraFunctions ในกรณีที่มี function หรือตัวแปรพิเศษก็สามารถใส่ในส่วนนี้ได้ครับ และสุดท้าย !MAEMOD_End เป็นตัวบอกว่าสมการหรือค่าต่างๆสิ้นสุดที่บรรทัดนี้ครับ พูดง่ายๆก็คือมีคีย์เวิร์ด อยู่ 6 คำคือ !Equations, !Parameters, !Inits, !Outputs, !ExtraFunctions และ !MAEMOD_End ครับ ไม่จำเป็นต้องเรียงตามลำดับนี้นะครับ อันจะขึ้นก่อนหลังก็ได้
2. วิธีรันก็เพียงใช้คำสั่ง maemod.ode เช่น
ต้องการจะคำนวณสมการข้างบนโดยที่ ค่า t เริ่มต้นที่ 0 เพิ่มขึ้นที่ล่ะ 0.1 จนถึง 20*pi

out<-maemod.ode(input.filename = "test.txt",timegrid = seq(0,20*pi,0.1))
head(out)  time Y1 Y2 
[1,] 0.0 0.0000000000 0.000000000 
[2,] 0.1 0.0001663662 0.004991383 
[3,] 0.2 0.0013277223 0.019866019 
[4,] 0.3 0.0044590899 0.044327146 
[5,] 0.4 0.0104962890 0.077883467 
[6,] 0.5 0.0203162441 0.119856470
plot(out[,c(2,3)],col="red")

heart

อีกตัวอย่างครับ สำหรับแก้สมการลอเร้นซ์   แต่แทนที่จะเซฟสมการและพารามิเตอร์ใน text file เราสามารถสร้างเป็นตัวแปรเก็บข้อความของระบบที่มีตัวแปรต่างๆได้ตามนี้เลยครับ (สังเกตุตัวแปรที่ชื่อ Lorenz ครับ)

library(scatterplot3d)
library(maemod)
lorenz<-"
 !Equations
 dx<-sigma*(y-x)
 dy<-x*(rho-z)-y
 dz<-x*y-beta*z
 
 !Parameters
 sigma=10, beta=2.66666, rho=28
 
 !Inits
 x=-10, y=-12, z=30.05
 
 !Outputs
 c(dx,dy,dz)

 !Plots
 !ExtraFunctions
 
 !MAEMOD_End
 "
lorenzout<-maemod.ode(input.text = lorenz, timegrid = seq(0,30,0.01))

scatterplot3d(lorenzout[,c(2,3,4)],type = 'l')

lorenzถ้าสนใจอยากติดตั้ง package นี้ก็สามารถทำได้ตามนี้เลยครับ

 library(devtools)
 install_github("slphyx/maemod")

code ทั้งหมดอยู่ที่ https://github.com/slphyx/maemod ครับ

จริงๆแล้วใน maemod นี้เราสามารถเลือกใช้ methods ต่างๆ เช่น lsoda, rk4 และอื่นๆอีกมากมาย สำหรับแก้ระบบสมการอนุพันธ์นี้ได้ครับ โดยวิธีการเลือกใช้ methods เหล่านี้สามารถดูได้ที่ package deSolve (http://desolve.r-forge.r-project.org/index.html) เลยครับเพราะค่าพารามิเตอร์สำหรับmethods ต่างๆนี้จะถูกส่งไปเรียกจาก deSolve อีกทีครับ

หากอยากช่วยเขียนปรับปรุงก็ Pull requests หรือ Fork ได้เลยครับ

แบ่งคำภาษาไทยใน R ด้วย LexTo

มีคนส่งข้อความมาว่าให้ช่วยทำให้ดูหน่อยว่าจะเอาโปรแกรมตัดคำภาษาไทย http://www.sansarn.com/lexto/ ซึ่งเขียนด้วยภาษา Java โดย Choochart Haruechaiyasak มาใช้ใน R ได้อย่างไร
ด้วยความที่เห็นว่าผู้ถามเป็นหญิง แถมส่งการ์ตูนมาด้วยว่าร้องไห้หนักมาก ไอ้เราก็เป็นคนใจอ่อนด้วยสิ เลยทำให้ดูแบบคร่าวๆตามนี้ครับ
R สามารถที่เรียกโปรแกรมที่เขียนด้วย Java มาใช้ใน R หมายถึงมีการส่งผ่านค่าหรือรับค่าต่างๆจากโปรแกรมนั้นได้โดยใช้คำสั่งที่อยู่ในpackageอย่าง rJava ครับรายละเอียดก็ไปหาอ่านเอาเองนะครับ
โปรแกรม LexTo ที่ให้โหลดกันนั้นจะมีfunction main อยู่ในไฟล์ LongLexTo.java ครับ ผมก็แก้ไขอะไรบางอย่าง(จำไม่ได้ ต้องเปิดดู) หลักๆก็วิธีที่เขียนผลลัพท์ออกมา แล้วก็คอมไพล์ใหม่ซึ่งเราก็จะได้เป็น .class มาครับ

ส่วนอันนี้ก็เป็น code ที่เขียนเพื่อเรียกใช้ function main ของโปรแกรม LongLexTo ที่คอมไพล์แล้วครับ
library(rJava)

.jinit()
.jaddClassPath(“D:\\works\\LongLexTo\\R”) # replace with the path to the folder containing LongLexTo class file
.jclassPath()

# export the input string to a text file
writeinput<-function(inputstring){
inputfile<-file(“RLongLexToinput.txt”)
writeLines(inputstring,inputfile,useBytes=T)
close(inputfile)
}

## call the main function in LongLexTo
RLongLexToF<-function(inputfilename,outputfilename){
J(‘LongLexTo’,’main’,c(inputfilename,outputfilename))
}

RLongLexToC<-function(inputtext){
writeinput(inputtext)
inputfilename <- “RLongLexToinput.txt” # input file
outputfilename <- “RLongLexTotemp.txt” # temp output file
RLongLexToF(inputfilename,outputfilename)
outtxt<-as.vector(strsplit(readLines(outputfilename,encoding=”UTF-8″),”[|]”)[[1]])
outtxt
}

setwd(“D:\\works\\LongLexTo\\R”) # set the path to your dictionary file

ผลที่ได้ก็ประมาณนี้ครับ

RLexLongTo

ผมลองกับข้อความแบบต่างๆแล้วรู้สึกว่าจะมีปัญหาเรื่อง encoding อยู่ครับ ต้องขอให้ผู้ที่รู้เรื่องทางด้านนี้หรือใครก็ตามที่อยากปรับปรุงให้มันดีขึ้นมาช่วยแล้วล่ะครับ

ผมทำเป็น R package แล้วที่ https://github.com/slphyx/RLongLexTo

ลองดูเพิ่มเติมที่นี่อีกครับ

ส่วนตัวแล้วผมอยากจะบอกว่าคำสั่งสำหรับจัดการเรื่องข้อมูลประเภท string จาก package ชื่อ stringr หรือ stringi ครับ ก็มีเรื่องการแบ่งคำเช่นกันครับ  เช่น stringr มีคำสั่งช่วยเรื่องแบ่งคำอยู่แล้วซึ่งใช้ได้กับภาษาไทยด้วยอย่าง str_split ที่เราสามารใช้แยก string ให้ได้เพียงแค่บอกว่าจะแยกเป็นคำหรือเป็นประโยค

##

ผมเขียนpackageสำหรับแบ่งคำโดยใช้ LexTo อีกตัวครับเรียกมันว่าอะไรวะ https://github.com/slphyx/araiwa เป็นตัวอย่างแบบง่ายที่ผมใช้สอนเรื่องการใช้.net ในR ครับ

สมการดอกกุหลาบ

Rose[x_,theta_]:=Module[{phi=(Pi/2)Exp[-theta/(8 Pi)],X=1-(1/2)((5/4)(1-Mod[3.6 theta,2 Pi]/Pi)^2-1/4)^2},
y=1.95653 x^2 (1.27689 x-1)^2 Sin[phi];
r=X(x Sin[phi]+y Cos[phi]);
{r Sin[theta],r Cos[theta],X(x Cos[phi]-y Sin[phi])}
];

ParametricPlot3D[Rose[x,theta],{x,0,1},{theta,-2 Pi,15 Pi},PlotPoints->{25,576},PlotStyle->Red,Mesh->None,Axes->False,Boxed->False]

rose

ลอกมาจาก www.bugman123.com

 

เรียกใช้งาน R ใน Mathematica

สำหรับคนที่สนใจหรือใช้งาน R ใน Mathematica (version < 9.0) ลองดูตัวอย่างที่นี่นะครับ http://mathematica.stackexchange.com/questions/844/are-there-any-rlink-like-projects-which-enable-the-interaction-between-r-and
ซึ่งต้องติดตั้ง RAndFriends (http://rcom.univie.ac.at/download.html) ก่อนนะครับ (แนะนำเลยครับตัวนี้ สะดวกมากๆ)

ตัวอย่าง Code

Needs[“NETLink`”]
myR = CreateCOMObject[“StatConnectorSrv.StatConnector”]
myR@Init[“R”]
myR@SetSymbol[“xxx”, 12321]
result1 = myR@GetSymbol[“xxx”]
myR@EvaluateNoReturn[“randmat<-matrix(rnorm(100),10)”]
rmat = myR@GetSymbol[“randmat”]
result2 = myR@Evaluate[“solve(matrix(1:4,2))”]

เพิ่มเติม
R http://mpec.sc.mahidol.ac.th/forums/index.php/topic,2817.0.html
RStudio http://mpec.sc.mahidol.ac.th/forums/index.php/topic,5184.0.html

สำหรับใครที่ใช้ Mathematica version 9.0 ขึ้นไปสามารถที่จะเรียกใช้งาน R ได้โดยตรงจาก package ชื่อ RLink ซึ่งมากับตัว Mathematica ได้เลยครับสะดวกมาก ผมเขียนการใช้งานแบบง่ายของ RLink ไว้ที่นี่ครับ การใช้งาน RLink แบบง่ายๆ

%d bloggers like this: