หา drive ของ USB drive

ทีมที่ต้องไปนำเสนองานเพื่อขอเงินล้านทีมหนึ่งต้องการใช้ Shiny ขอมาว่าให้ช่วยหน่อย โดยที่มีความต้องการว่าไม่ต้องการให้มีเซ็ตหรือเปิดอะไรยุ่งยากเพียงแค่ เสียบ USB drive ในเครื่องลูกค้าซึ่งเป็น Windows แล้ว double click อะไรก็แล้ว ให้ตัว Shiny app ก็เปิดขึ้นมาเลย ผมเลยบอกว่าได้ง่ายมาก เลี้ยงก๋วยเตี๋ยวผมก่อนชามหนึ่งเดี๋ยวเขียนscript ง่ายๆให้ เวลาใช้ก็เพียง double click ที่ icon ของ batch file นี้

วิธีที่ผมทำนั้นมันง่ายจริงๆครับ เพียงเขียน batch file หาว่า drive ที่เข้าเสียบนั้นอยู่ drive อะไรก่อน จากนั้นก็เพียง set ค่าพารามิเตอร์ที่ rstudio ต้องการใช้ในการหา R  และก็แก้ script นิดหน่อยให้ R มันโหลดตัว app เลย

อันนี้เป็นตัวอย่างโค้ด batch file ที่ใช้หา USB drive ที่ชื่อว่า MONEY ครับ  ไอเดียก็มีว่าใช้ wmic เขียนว่าUSB drive นั้นdrive อะไรแล้วเขียนลงไฟล์ชื่อ wmic.txt จากนั้นก็เปิดไฟล์ wmic.txt อ่าน พร้อมกับเช็ตตัวแปรชื่อ USBDrive จากนั้นก็เอาไปทำอะไรที่เราต้องการได้ครับ ซึ่งตัวอย่างนี้ผมก็เอาไปเปิดไฟล์ที่ slphyx.dat โชว์บน screen ครับ

wmic LOGICALDISK where volumename="MONEY" get deviceID > wmic.txt
for /f "skip=1" %%b IN ('type wmic.txt') DO (set "USBDrive=%%b")
type %USBDrive%\practices\slphyx.dat

 

ส่วนใครที่อยากรู้ว่าเกิดอะไรขึ้นหลังจากที่เราเรียกใช้ R ก็ดูตามนี้เลยครับ

เครดิต: https://twitter.com/thomasp85

 

เพิ่มเติม  https://rviews.rstudio.com/2017/04/19/r-for-enterprise-understanding-r-s-startup/

https://cran.r-project.org/web/packages/startup/vignettes/startup-intro.html

Continue reading “หา drive ของ USB drive”

LexTo บน Windows

ผมเอา code LexTo เค้ามาลองเขียนเล่นสำหรับใช้งานแบบ offline บน Windows (7, 8 และ 10)ครับ

สนใจdownload ได้ที่นี่ครับ

ที่download มันจะเป็นไฟล์ zip ที่มีตัวโปรแกรมชื่อ Araiwa.exe กับไฟล์ dictionary ชื่อ lexitron.txt พร้อมกับไฟล์ araiwadll.dll ก็ให้แตกไฟล์ zip นี้ออก แล้วdouble click ที่ไฟล์ Araiwa.exe ได้เลยครับ

ส่วนใครที่อยากใช้มันใน R ผมเขียนเป็นpackage เรียกมันว่า araiwa ครับ ดูเพิ่มเติมได้ที่ https://github.com/slphyx/Araiwa

ใช้งาน mono+rdotnet บน Rocks cluster

ตัวอย่างการใช้งาน mono + Rdotnet บนระบบ Rocks cluster ครับ

เวอร์ชั่น Rocks cluster ที่ผมใช้คือ 6.2 ครับ การติดตั้งก็แบบเดิมๆเลยตามที่อธิบายในเอกสารบนเวบของ Rocks เลย ไม่มีอะไรพิเศษ จากนั้นก็ผมก็ yum ติดตั้ง mono จาก https://copr.fedorainfracloud.org/coprs/tpokorra/mono-opt/  โดยในเวอร์ชั่นนี้ mono จะถูกติดตั้งไว้ที่ /opt/mono และก็ yum ติดตั้ง R ซึ่ง R จะถูกติดตั้งไว้ที่ /usr/lib64/R ของ head node ครับ

หลังจากที่ติดตั้ง mono และ R เรียบร้อยแล้วก็เอา code ของ C# ที่เขียนสำหรับเรียกใช้งาน rdotnet บวกกับก็อปปี้ไฟล์แอสเซมบลีของ Rdotnet ต่างๆมาไว้ใน folder ที่ต้องการก่อนทำการคอมไพล์ครับ โดยไฟล์ต่างๆของ Rdotnet ก็มีอย่างเช่น DynamicInterop.dll, RDotNet.dll, RDotNet.NativeLibrary.dll

ก่อนคอมไพล์หรือเรียกใช้งาน mono เราก็ต้องโหลดenviroment ต่างๆของ mono ก่อน โดยการพิมพ์

$ . /opt/mono/env.sh

ซึ่งมันก็คือเซ็ตpath ต่างๆของตัวแปรอย่าง LD_LIBRARY_PATH กับ PKG_CONFIG_PATH ครับ

export PATH=/opt/mono/bin:$PATH
export LD_LIBRARY_PATH=/opt/mono/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=/opt/mono/lib/pkgconfig:$PKG_CONFIG_PATH

จากนั้นก็ export ค่า R_HOME ไปยัง path ของ R ที่ติดตั้งแล้ว

$ export R_HOME = “/usr/lib64/R”

อันนี้เป็นตัวอย่าง code ที่ผมก็อปปี้มาจากเวบของ RDotnet ครับ สำหรับเรียก R มาเพื่อทำ t-test ของเลข 2 ชุดครับ

#testRDotNet.cs
using System;
using System.Linq;
using RDotNet;

namespace Sample1
{
 class Program
 {
 static void Main(string[] args)
 {
 REngine.SetEnvironmentVariables();
 REngine engine = REngine.GetInstance();
 // REngine requires explicit initialization.
 // You can set some parameters.
 engine.Initialize();

// .NET Framework array to R vector.
 NumericVector group1 = engine.CreateNumericVector(new double[] { 30.02, 29.99, 30.11, 29.97, 30.01, 29.99 });
 engine.SetSymbol("group1", group1);
 // Direct parsing from R script.
 NumericVector group2 = engine.Evaluate("group2 <- c(29.89, 29.93, 29.72, 29.98, 30.02, 29.98)").AsNumeric();

// Test difference of mean and get the P-value.
 GenericVector testResult = engine.Evaluate("t.test(group1, group2)").AsList();
 double p = testResult["p.value"].AsNumeric().First();

Console.WriteLine("Group1: [{0}]", string.Join(", ", group1));
 Console.WriteLine("Group2: [{0}]", string.Join(", ", group2));
 Console.WriteLine("P-value = {0:0.000}", p);

// you should always dispose of the REngine properly.
 // After disposing of the engine, you cannot reinitialize nor reuse it
 engine.Dispose();

}
 }
}

เวลาคอมไพล์ก็เพียงพิมพ์

$ mcs /reference:RDotNet.dll /reference:RDotNet.NativeLibrary.dll /reference:DynamicInterop.dll testRDotNet.cs

ซึ่งคำสั่ง mcs นี้จะแปลงไฟล์ .cs ของเราให้เป็น binary ไฟล์ที่คอมพิวเตอร์จะเข้าใจได้ 🙂 ครับ ซึ่งในที่นี้มันจะสร้างไฟล์ชื่อ testRDotNet.exe ให้ครับ ส่วนoption ของคำสั่ง /reference เป็นการบอกว่าเราเรียกใช้ namespace จากไฟล์แอสเซมบลี่อะไรบ้าง

วิธีการรันไฟล์ exe ที่ได้จาก mcs ก็เพียงพิมพ์ mono แล้วตามด้วยไฟล์ exe ครับ เช่น

$ mono testRDotNet.exe

Welch Two Sample t-test

data: group1 and group2
t = 1.959, df = 7.0306, p-value = 0.09077
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.01956909 0.20956909
sample estimates:
mean of x mean of y
 30.015 29.920

Group1: [30.02, 29.99, 30.11, 29.97, 30.01, 29.99]
Group2: [29.89, 29.93, 29.72, 29.98, 30.02, 29.98]
P-value = 0.091

 

 

word cloud ภาษาไทยใน R

ตัวอย่างการทำเมฆกลุ่มคำใน R ครับ (Windows10 + R > 3.2 + RStudio 0.99.903)

library ที่จะใช้มีสองตัวคือ RLongLexTo (ดูวิธีติดตั้งที่ https://github.com/slphyx/RLongLexTo) กับ wordcloud2 (https://github.com/Lchiffon/wordcloud2)

library(RLongLexTo)
library(wordcloud2)

เซ็ต LC_CTYPE ให้ใช้ภาษาไทยครับ

Sys.setlocale("LC_CTYPE","Thai")

จากนั้นก็สร้างtext file ของข้อความที่ต้องการสร้างเมฆกลุ่มคำ ในที่นี้ผมcopyข้อความมาจาก http://king.kapook.com/royal_words_2545.php แล้วสร้างเป็นไฟล์ชื่อtest.txt อันนี้ทำง่ายๆเลยครับโดยการลากเม้าส์ ไฮไลท์ข้อความที่ต้องการบนweb browser (MS Edge) แล้วกด ctlr+c เพื่อcopy แล้วก็เอาไปวางในnotepad (ctrl+v) แล้วก็save โดยที่ตอนเซฟผมเลือก Encoding เป็น ANSI จากนั้นก็ใช้คำสั่ง RLongLexToF เพื่อทำการแยกคำโดยคำสั่งนี้จะสร้างไฟล์outputออกมา(ผมให้ชื่อ outtest.txt ครับ) โดยที่แต่ล่ะคำจะแยกกันโดยมีเครื่องหมาย “|” คั่นอยู่

RLongLexToF(inputfilename = "test.txt",outputfilename = "outtest.txt")

จากนั้นก็อ่านไฟล์ที่แยกคำแล้วมาสร้างเป็นvector ตามนี้ครับ

outtxt<-as.vector(strsplit(readLines("outtest.txt"),"[|]")[[1]])

พอได้vectorของแต่ล่ะคำแล้วก็สร้าง data frame สำหรับนับว่าแต่ล่ะคำนั้นมีความถี่หรือมีจำนวนเท่าใด

wordfreq<-as.data.frame(table(outtxt))

จากนั้นก็เอาตัวแปรสำหรับเก็บความถึ่ของคำนี้ไปสร้างwordcloudได้เลยครับ

wordcloud2(wordfreq,color = "random-light",shape = 'star',backgroundColor = "black")

star

ส่วนอันนี้ก็เป็นอีกตัวอย่างครับ โดยที่ไฟล์ข้อความผมcopyมาจาก http://king.kapook.com/royal_words_2548.php

RLongLexToF(inputfilename = "test2.txt",outputfilename = "outtest2.txt")
outtxt2<-as.vector(strsplit(readLines("outtest2.txt"),"[|]")[[1]])

wordfreq2<-as.data.frame(table(outtxt2))
wordcloud2(wordfreq2)

cloud2

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 console จะรับได้ในหนึ่งคำสั่ง

กำลังเขียน library ที่แปลงสมการ ode เป็นfunctionใน R ปรากฏว่าระหว่างที่ทดสอบสมการซึ่งยาวพอสมควร(ประมาณ 40 สมการ) function ที่เขียนไม่สามารถทำตามที่สั่งได้ มีบางส่วนของสมการถูกตัดไป เลยค้นข้อมูลเจอว่า console ของ R จะ limit ความยาวของคำสั่งไว้ที่ 4095 bytes (ไม่ใช่จำนวนตัวอักษร)

https://cran.r-project.org/doc/manuals/R-intro.html#R-commands_003b-case-sensitivity-etc

ปัญหาติดตั้ง PsN บน Rocks

PsN บอกว่าต้องการโมดูล perl Archive::Zip แต่ปรากฏว่า พอลง perl-Archive-Zip หรือ perl-Archive-Any แล้วมันก็ยังมีปัญหา

ตัวโมดูลที่ถูกต้องสำหรับลงบน Rocks (CentOs 6.6) คือ perl-Compress-Raw-Zlip