ggplot2でX軸の大小を反転させる方法(factorの場合)

はじめに

ggplot2でX軸の大小を反転させる方法について

無指定の場合

ggplot2で描画する際にcoord_flip()を使用するとX軸とY軸を入れ替えることができる。
ただし、その場合には順番が小さい方が下にきてしまい、思い通りの図にならない。

library(ggplot2)

p <- ggplot(iris)
p + aes(x = Species, y = Sepal.Length) +
     geom_boxplot() +
     coord_flip()

plot of chunk unnamed-chunk-1

reorder関数とdplyr::desc関数を使用する場合

このサイトの内容を参考にしました。

reorder関数を使用することでfactorの順序を変えることができる。
この時dplyrパッケージのdesc関数で降順に変換する。

ただし、後に示しているが、
forcatsパッケージのfct_rev関数を使用する方法が最も簡単である。

library(ggplot2)

p + aes(x = reorder(Species, dplyr::desc(Species)),
        y = Sepal.Length) +
     geom_boxplot() +
    coord_flip()

plot of chunk unnamed-chunk-2

forcatsパッケージのfct_rev関数を使用する場合

ここではforcatsパッケージのfct_rev関数を使用した方法を示す。
この関数はfactorの順序を反転させるものである。

したがって、個人的にはこの方法を使用することにする。

library(ggplot2)
library(magrittr)
library(forcats)

p + aes(x = Species %>% fct_rev, y = Sepal.Length) +
     geom_boxplot() +
     coord_flip()

plot of chunk unnamed-chunk-3

forecatsパッケージを読み込まない場合には以下のようにする。

library(ggplot2)
library(magrittr)

p + aes(x = Species %>% forcats::fct_rev(), y = Sepal.Length) +
     geom_boxplot() +
     coord_flip()

LibreOfficeでNoto Sans/Noto Serifフォントを使用する (Windows, Linux)

経緯

最近、LaTeX (LuaLaTeX) で資料を作成する際のフォントとして「源ノ角ゴシックおよび源ノ明朝」を使用するようになりました。かなり綺麗なフォントであると感じたので、 LibreOfficeでも使用したいと思いました。

OSはLinuxとWindowsを併用しているため、どちらのLibreOfficeでも同じように表示されるかどうかを試してみたところ、「源ノ角ゴシックおよび源ノ明朝」では上手くいきませんでした。

試行錯誤した結果、「Noto SansおよびNoto Serif」を使用したところ成功したので、その結果をメモとして残しておきます。

手順

ダウンロードするファイル

このページ の下の方にある “Region-specific Subset OpenType/CFF (Subset OTF)” からダウンロードしました。

  • Noto Sansフォント
    • NotoSansJP-[weight].otf (NotoSansfJP.zip)
    • ファイルの内容
      • NotoSansJP-Thin.otf
      • NotoSansJP-Light.otf
      • NotoSansJP-DemiLight.otf
      • NotoSansJP-Regular.otf(必須)
      • NotoSansJP-Medium.otf
      • NotoSansJP-Bold.otf(必須)
      • NotoSansJP-Black.otf
  • Noto Serifフォント
    • NotoSerifJP-[weight].otf (NotoSerifJP.zip)
    • ファイルの内容
      • NotoSerifJP-ExtraLight.otf
      • NotoSerifJP-Light.otf
      • NotoSerifJP-Medium.otf
      • NotoSerifJP-Regular.otf(必須)
      • NotoSerifJP-SemiBold.otf
      • NotoSerifJP-Bold.otf(必須)
      • NotoSerifJP-Black.otf

フォントのインストール

ダウンロードしたNotoSansJP.zipおよびNotoSerifJP.zipファイルを解凍すると NotoSansJPおよびNotoSerifJPフォルダが作成されます。

Windowsの場合

解凍してできたファイルを右クリックするとメニューが現れるため、そこから「フォントのインストール」を選択します。

Linuxの場合

/usr/local/share/fonts/opentype/google/ 以下にフォントを配置しました。

LibreOfficeでのフォント選択

フォントの選択は以下の通りに行います。

申し訳ありませんが画像は省略します。

Noto Sans JP

ゴシック体にする場合には少し面倒です。

  • 通常の文字:”Noto Sans JP Regular”を選択
  • ボールド体:”Noto Sans JP Bold”を選択
    • “Noto Sans JP Regular”を選択後に太字(Ctrl+B)にしても “Noto Sans JP Bold”にはなりません。

Noto Serif JP

明朝体の場合は簡単(通常通り)です。

  • 通常の文字:”Noto Serif JP”を選択
  • ボールド体:”Noto Serif JP”を選択後に太字(Ctrl+B)

源ノ角ゴシックおよび源ノ明朝の場合(失敗)

源ノ角ゴシック

源ノ角ゴシックの場合には7ウェイトとも WindowsおよびLinuxの両方で問題なく使用する事ができました。

源ノ明朝

源ノ明朝をWindowsおよびLinuxの両方で使用しようとすると以下のようにフォント名が異なるため上手くいきませんでした。

また、LibreOfficeのフォント置換テーブルではフォントを別なものに置換することはできても、太字(ボールド体)に変換することはできませんでした(この理由によって源ノ明朝の使用を断念)。

他の5ウェイト (ExtraLight, Light, Medium, SemiBold, Black) を使用した場合には問題なく使用することができました。

Linuxの場合

このページ の内容を参考にさせて頂きました。

  • 通常の文字:”Source Han Serif JP”を選択
  • ボールド体:”源ノ明朝 JP”を選択

Windowsの場合

  • 通常の文字:”源ノ明朝 JP”を選択
  • ボールド体:”源ノ明朝 JP”を選択後に太字(Ctrl+B)

カテゴリカルデータからダミー変数を作成するR関数を自作(複数列対応可)(CRANに登録)

以前、 このページ でカテゴリカルデータからダミー変数を作成するR関数を紹介し、 GitHub で公開しました。関数が1つだけの非常に簡単なものです。

時々検索されているようなので、英語に不安はありますが思い切ってCRANに投稿してみました。

対応して頂いたのはUwe Ligges氏でした。「パッケージの説明文(Description)が理解しにくい」と指摘を受けたため、少し改善して再投稿したところアクセプトされました。

パッケージの説明は このページ にあります。

Rからは

install.packages("makedummies")

でインストールできます。

使用方法はGitHubの例を参照して下さい。

Vine LinuxのRでR commanderを使用できるように変更

VineSeedのRではR commanderを使用することができましたが、 Vine Linux 6では使用することができませんでした。

R commanderを使用するためには tcl-8.5/tk-8.5 が必要なのですが、 Vine Linux 6ではバージョンが8.4だったためです。

そこでtcl85/tk85パッケージを作成することで R commanderを使用することができるようになりました。

※ただし、現状の6.3ではproposed-updatesを適用する必要があります。 6.5βではそのままで使用できます。

sudo apt-get install apt-sourceslist-proposed-updates # 6.3の場合に必要
sudo apt-get update
sudo apt-get install R

これで使用者が少しでも増えるといいです(願望)。

anything-swoopを使用するための設定

経緯

Emacsでanythingを使用しています(helmをあまり使用したくないため)。

現在、ace-isearch を使用していますが、この設定では6文字以上の検索でhelm-swoopを使用してしまいます。

anything-swoopを公開している方を見つけたので、 ace-isearchからanything-swoopを使用するように設定しました。

手順

cmigemoの設定

;; cmigemo: https://github.com/kron/cmigemo

(require 'migemo)
(setq migemo-command "cmigemo")
(setq migemo-options '("-q" "--emacs"))

;; Set your installed path
(setq migemo-dictionary (expand-file-name "/usr/share/migemo/utf-8/migemo-dict"))
;; 辞書の場所に合わせて適切に変更

(setq migemo-user-dictionary nil)
(setq migemo-regex-dictionary nil)
(setq migemo-coding-system 'utf-8-unix)
;; migemoを起動する
(load-library "migemo")
(migemo-init)

;; キャッシュの設定
(setq migemo-use-pattern-alist t)
(setq migemo-use-frequent-pattern-alist t)
(setq migemo-pattern-alist-length 1024)

anything-swoopのダウンロード

このページ からanything-swoop.elをダウンロードしてパスの通った場所に保存する。

ace-searchからanything-swoopを使用するための設定

(require 'ace-isearch)
(custom-set-variables '(ace-isearch-function-from-isearch 'anything-swoop-from-isearch))
(custom-set-variables '(ace-isearch-fallback-function 'anything-swoop-from-isearch))
(global-ace-isearch-mode 1)

以上の設定でanything-swoopを使用することができます。

ワード、エクセル、PDFなどのファイルをテキスト形式として書き出す

経緯

Microsoft Wordのファイル(doc/docx)やopendocument(odt)、 PDFファイルの内容を確認する際に、これらのアプリケーションを開かなくてもすむようにテキスト形式に変換してくれるアプリケーションがあります(antiword, pandoc, pdftotext)。

ただし、

  • doc形式のファイルはantiword
  • docx形式のファイルはpandoc
  • pdfファイルはpdftotext

のようにすべてアプリケーションが異なり、しかも使用オプションも異なります。

そこでこれらのコマンドを1つにまとめてみました。

同時にMicrosoft Excelのファイル(xls/xlsx)やopendocument(ods)もテキスト形式に変更できるようにしてみました。

内容

必要なアプリケーション

  • antiword (doc)
  • pandoc (docx, odt, html)
  • pdftotext (pdf)
  • gnumeric (xls, xlsx, ods => html)
  • w3m (xls, xlsx, ods)

上2つのアプリケーションについては Vine Linux用のrpmパッケージを自分自身で作成してアップロードしています。

シェルスクリプト

GitHub で公開しています。

基本的にファイルの拡張子で分岐し、標準出力に出力するようにしているだけです。

新たなファイルに保存するのは使い勝手が悪いと感じたため標準出力に表示するようにしています。

#!/bin/sh
# require pdftotext (pdf)
# require antiword (doc)
# require pandoc (docx/odt/html/tex)
# require gnumeric and w3m (xls/xlsx)

set -e

if [ $# -eq 0 ]; then
  echo "Need argument(s): pdf, doc(x), xls(x) or ... file(s)" 1>&2
  exit 1
fi

for i in $*
do
    if [ -f ${i} ]
    then
       ext="${i##*.}"
       case $ext in
           pdf) pdftotext -raw ${i} - ;;
           doc) LANG=ja_JP.utf8 antiword -w 0 ${i} ;;
           docx|odt|html|htm|tex) pandoc -t plain ${i} ;;
           xls|xlsx|ods) tmpfile=$(mktemp).html ;
                         ssconvert -T Gnumeric_html:xhtml ${i} ${tmpfile} 2> /dev/null ;
                         w3m -dump ${tmpfile} ;
                         rm -f ${tmpfile} ;;
           *)    ;;
       esac
    fi
done

doc

Emacs上で antiword を使用したときに”LANG=ja_JP.utf8″ をつけないと文字化けしたため、環境変数を一時的に設定しています。

docx/odt/html/htm/tex

pandoc の機能をそのまま使用しているだけなので、必要に応じて対応している形式を追加すればいいです。

xls/xlsx/ods

今回苦労したのがこれらのスプレッドシートです。

調べていると gnumeric に含まれる ssconvert というコマンドで html形式に変換できることが分かったため、それを使用しました。 html形式に変換した後に w3m の-dumpオプションでテキスト形式に変換しています。

pandocでhtmlをテキスト形式に変換すると表のレイアウトが崩れてしまったため、今回はw3mを使用しています。

使用法

実行権限をつけて

convertdoc file1 file2 ...

のようにすると、全てのファイルがつながって標準出力に表示されます。

存在しないファイルおよび対応していないファイルは無視されます。エラーも出ないようにしています。

応用

以下のようなelispスクリプトを書き、 M-x my-convertdoc の後に開きたいファイルを選択するとファイルの内容を確認することができます。

Emacs上でMewを使用しており、添付ファイルの内容を確認したかったというのがそもそもの始まりです。

添付ファイルを保存してから M-x my-convertdoc コマンドを実行しなければならないため手間はかかりますが、それでも楽になりました。

elispスクリプト

(defvar my-convertdoc-command "convertdoc")
(defvar my-convertdoc-defaultdir "~/ramdisk/") ;; デフォルトのフォルダ(任意の場所)

(require 'f)

(defun my-convertdoc (file)
  (interactive
   (list (read-file-name "Input file name: "
                         my-convertdoc-defaultdir nil t)))
  (my-convertdoc-file file))

(defun my-convertdoc-file (file)
  (let ((filename (shell-quote-argument (f-expand file)))
        (buf "*ConvertDoc*")
        (resize-mini-windows nil))
      (shell-command
       (format "%s %s" my-convertdoc-command filename) buf)
      (with-current-buffer buf
        (view-mode))))

カスタムメニューの内容をpecoで選択するためのスクリプトを作成

経緯

以前はfluxboxを使用しており、右クリックでメニューが出てきました。そのメニューはファイルを書き換えることでカスタマイズできました。

現在xmonadに移行しており、いくつかのキーにアプリケーションを割り当てています。

割り当てるアプリケーションが多くなると覚えるのが大変なので、カスタマイズできるメニューがないかと探していたのですが見つかりませんでした(探し方が悪いため?)。

そこで自分でスクリプトを書きました。慣れていないので多少時間はかかりました。

内容

Rubyスクリプト

GitHub で公開しています。

#!/usr/bin/env ruby
# coding: utf-8

# peco binary
PECO = File.expand_path "/usr/bin/peco"

# terminal emulator (xterm/urxvt/mlterm)
XTERM = "mlterm"

# menu list
menufile = File.expand_path "~/.mymenu"


require 'tempfile'

class MyMenu
  def initialize(menufile)
    @menufile = menufile
    @appfilepath = Tempfile.new("tmpnew").path
    @hash = Hash.new
  end

  protected

  def set_hash_and_list
    io1 = File.open(@menufile, "r")     # filelist
    io2 = File.open(@appfilepath, "w")  # list of application name

    io1.each {|line|
      line.strip!
      line.chomp!
      next if line == "" || (/^#/ =~ line)

      rows = line.split(/,/)
      rows[1] = rows[0] if rows[1].nil?
      @hash.store(rows[0], rows[1])
      io2.puts rows[0]
    }
    io1.close
    io2.close
  end

  def exec_peco
    out = Tempfile.new("peco-out")
    err = Tempfile.new("peco-err")
    system "#{XTERM} -e sh -c '#{PECO} #{@appfilepath} > #{out.path} 2> #{err.path}'"

    res = `cat #{out.path}`
    if res != ""
      app = @hash[res.chomp!]
      system("#{app} &")
    end
  end

  public

  def exec_MyMenu
    self.set_hash_and_list
    self.exec_peco
  end
end


mymenu = MyMenu.new(menufile)
mymenu.exec_MyMenu

このスクリプトの後半はるびきち様が公開している peco を参考にさせて頂きました。というよりもそのまま使用させて頂きました。

設定

mymenu.rb

XTERM に使用したいターミナルエミュレーターを指定します。

  • xterm/urxvt/mlterm であれば大丈夫でした。
  • gnome-terminal/lxterminal は失敗しました。

~/.mymenu

~/.mymenu を作成し、以下のように記載します。 このファイルが存在しないとエラーが出ます。

FD, gnome-terminal -e fd
R, lxterminal -e R
leafpad

メニューに表示したい内容と実行するコマンドをカンマで区切って記載するだけです。

  • カンマの左側に記載した内容がメニューに表示されます。
  • カンマの右側に記載した内容が実行されます。
    • 省略した場合には左側の内容がそのままコマンドとして実行されます。
    • ターミナルで実行したい場合には “(使用したいターミナル) -e (実行したいコマンド)” のように記載します。

使用法

mymenu.rbを好きなキーに割り当てます。

あとは好きなように絞り込みをするだけです。

Hit-a-Hint の設定をしておけば、「@」を押した後に候補の左端に表示されている文字を打ち込むことで即座に選択できるようになります。

xmonadでmagitを使用してコミット後に画面が固まったように見えたら

Emacsでmagitを使用しています。

ウィンドウマネージャとしてxmonadを使用し始めてからコミット時に画面が固まったようになりました。

このような場合には、ワークスペースを切り換えてから戻すと元のmagitの画面に戻ります。

(解決法が見つかったのですが偶然です)

xmobarのステータスバー上に新着メール数を表示する

経緯

これまではconkyで、自宅、職場、Gmailの新着メール数を表示させていました。

タイル型ウィンドウマネージャであるxmonadに移行する場合、 conkyの表示か隠されてしまうため使いにくいです。そこでステータスバーであるxmobar上に新着メール数を表示することができるようになったため、その方法をメモしておきます。

方法

xmobarにテキストを渡せばその通りに表示してくれるため、「新着メール数を含む文字列」を表示するスクリプトを作成しました。

checkmail.rbスクリプト

GitHub にスクリプトを置いています。

サーバ名、ユーザ名、パスワードを各個人の設定に合わせて変更します。この時、” “ではなく’ ‘で囲んだ方がいいです ” “で囲んだ場合、@があるとうまくいかないためです(\@とすればOK)。

使用方法は説明がなくても分かると思います。第4引数は、POP3であれば”pop3″、GmailなどのIMAPであれば”imap”を指定します。

最終行で文字列を表示させるので自由に変更します。

#!/usr/bin/env ruby
# coding: utf-8

require 'net/pop'
require 'net/imap'

$server1 = '******'
$name1 = '******'
$pass1 = '******'

$server2 = 'imap.gmail.com'
$name2 = '******@gmail.com'
$pass2 = '******'

########################################
# function
########################################

def get_n_mail (server, name, pass, connect)
  case connect
  when "pop3"
    pop = Net::POP3.new(server, 110)
    pop.start(name, pass)
    n = pop.n_mails
    pop.finish
    return n
  when "imap"
    imap = Net::IMAP.new(server, 993, true)
    imap.login(name, pass)
    imap.select('INBOX')
    search_criterias = ['UNSEEN']
    n = imap.search(search_criterias).length
    imap.logout
    imap.disconnect
    return n
  else
    # do nothing
  end
end


########################################
# get numbers of mail
########################################

n1 = get_n_mail($server1, $name1, $pass1, "pop3")
n2 = get_n_mail($server2, $name2, $pass2, "imap")


########################################
# Result
########################################

printf "mail1:%d/mail2:%d", n1, n2

なぜRubyでスクリプトを作成したのかというと、

require 'net/pop'
require 'net/imap'

でPOP3とIMAPの両方を扱えることが分かったからです。

※ただしVine Linux 6のRubyのバージョンが古く(1.8.7)このままではエラーが出るため、 ruby-opensshパッケージをインストールする必要がありました。

sudo apt-get install ruby-openssh

ただし、これとは別にRuby-2.2.0をインストールしているのですが、この場合は新たにパッケージをインストールしなくても動作しました。

.xmobarrcの設定

先程のcheckmail.rbを ~/.xmonad/ に置きます(場所は任意)。

commandsの所に

,Run Com ".xmonad/checkmail.rb" ["&"] "mail" 3000

を追加し、

template = " %StdinReader% }{ [<fc=#ff00ff>%mail%</fc>]",

などのように設定すれば完了です。

この場合は300秒(5分)ごとにサーバに確認し、新着メール数を返します。

感想

これでxmonadに移行することができそうです。

あとはステータスバーにアイコンを表示させることができればOKです。