Latest update on 2018年3月7日 (水) at 15:42:47.
【第527回】 締め切りと講義準備に追われる日々(2013年11月26日)
- 5:55起床。しかし4時間半睡眠ではきつい。椅子には座ったがそのまま二度寝してしまい,気がついたら7:10を過ぎていた。いかなごくぎ煮を胚芽米ご飯に載せ,冷や奴ともずく酢を添えた手抜き朝食を済ませてから,昨夜の検索結果に加えて今朝届いたメールで頼まれた本を発注した。往路バスは名谷行き8:03発。
- 今週は,今日と明日は講義こそないが締め切り原稿が多々あり,木曜の4コマ講義は普通にあるのに加え,金曜に東京大学での環境保健学講義が2コマ,土曜に統数研で行われるR研究集会での発表もあるので,胸突き八丁という感じ。気合いで乗り切る。
- 昨日締め切りだった原稿は,メールでお願いして,締め切りを延長していただいた。これで,今日締め切りの某査読の方を先に済ませることができる。慢性的に睡眠不足状態で仕事をしているので,眠気から逃れるため,仕事のBGMはサンボマスター『終わらないミラクルの予感アルバム』と大森靖子『魔法が使えないなら死にたい』の無限リピート。
- 群馬方面から日付計算についての質問メールが来た。以前,Excelに誕生日と死亡日が3231201などと入力されているデータ(百万の位が元号(1〜4で明治〜平成),十万と一万の位が年,千と百の位が月,その下が日という意味)から生存日数を計算する方法を質問され,
- A1に数値として3220529が入っているとします。
- B1に
=DATEVALUE(LOOKUP(VALUE(LEFT(TEXT(A1,"0"),1)),{1,2,3,4;"明治","大正","昭和","平成"})&MID(TEXT(A1,"0"),2,2)&"年"&MID(TEXT(A1,"0"),4,2)&"月"&RIGHT(TEXT(A1,"0"),2)&"日")
と入力すると,日付シリアル値が得られます。 - 次にC1に数値として4251109が入っているとします。
- D1に
=DATEVALUE(LOOKUP(VALUE(LEFT(TEXT(C1,"0"),1)),{1,2,3,4;"明治","大正","昭和","平成"})&MID(TEXT(C1,"0"),2,2)&"年"&MID(TEXT(C1,"0"),4,2)&"月"&RIGHT(TEXT(C1,"0"),2)&"日")
と入力すると,その日付シリアル値が得られます。 - 後は,E1に=DATEDIF(B1,D1,"Y")と入力すれば,満年齢がでますし,
- F1に=DATEDIF(B1,D1,"YM")と入力すれば,残りの何ヶ月か,が得られます。
- もちろん,(D1-B1)/365.24でも小数表示ですが年齢は出ます。
と答えておいたのだが,Excelでは1900年1月1日が日付シリアル値1であり,それ以前は未定義のため,明治32年(1899年)より前の誕生日の人については計算できないのだった。手計算するしかないのかという問い合わせだったが,手計算も大変なので,Rで計算する方法を答えた。RのISOdate()関数は1899年以前の日付も扱えるので,例えば明治32年7月1日生まれ,平成13年3月12日に亡くなった方の生存期間は,
ISOdate(2001,3,12)-ISOdate(1899,7,1)
とすれば,正しくTime difference of 37144 daysと返ってくる。この結果を365.24で割ると,101歳で亡くなった方ということがわかる。日付起算日以前のシリアル値をマイナスで返せばいいだけのことなのに未定義とは,Excel弱すぎ。
- ちなみに,LibreOffice-4.1.2のCalcでは,DATEVALUE関数が元号を扱えないので西暦変換する必要があるが,その代わりにマイナスのシリアル値が許されている。他の関数はほぼ同様に機能するので,ExcelでB1とD1に入れていた式を少し書き換えるだけで,明治32年以前生まれの人にも対応できる。A1に1321215と入力されているとき,B1に
=DATEVALUE(TEXT(LOOKUP(VALUE(LEFT(TEXT(A1,"0"),1)),{1,2,3,4;1867,1911,1925,1988})+VALUE(MID(TEXT(A1,"0"),2,2)),"0")&"年"&MID(TEXT(A1,"0"),4,2)&"月"&RIGHT(TEXT(A1,"0"),2)&"日")
と打てば,シリアル値-15が得られる。もちろん,B1に入れる式は,書式を数値のStandardにしておけば,
=DATE(LOOKUP(VALUE(LEFT(TEXT(A1,"0"),1)),{1,2,3,4;1867,1911,1925,1988})+VALUE(MID(TEXT(A1,"0"),2,2)),VALUE(MID(TEXT(A1,"0"),4,2)),VALUE(RIGHT(TEXT(A1,"0"),2)))
でもいい。
- 日経サイエンス2014年1月号のNEWS SCAN海外WATCHの中に「BMIよりも優れた指標は?」という記事があって,今年8月のScienceにBMIを健康状態の予測変数として使うことの限界について調べた最新で最も包括的な研究が掲載されたことに触れ,身長・体重に加えて腹囲も考慮したABSI (A Body Shape Index)が「身長・体重・腹囲を打ち込むと簡単に計算してくれる指標がウェブ上にたくさんある」と紹介されていたが,ABSIを検索してヒットした第295回 ボディシェイプ指数 vs BMI Nice Body Make・・・よもやま話/ウェブリブログは有用な記事だと思う。原論文はPLoS oneで全文公開されているのだが,この記事にはそれへのリンクもあるのが素晴らしい。ちなみにABSIは,NHANESのデータを使って,身長と体重を対数変換した値を説明変数(=独立変数),腹囲を対数変換した値を目的変数(=従属変数)として重回帰分析をしたところ,重相関係数の二乗が0.829とかなりの説明力を示したので,そこから式変形して簡単な整数比乗で表される比例関係を求め,この比例関係から予想される腹囲に対して実際の腹囲が示す比,本来は米国民に適した指標と考えられる。計算式は,腹囲(m)をBMIの2/3乗と身長(m)の平方根の積で割るだけと簡単なので,Rならば,一度
ABSI <- function(HT=170, WT=80, WC=88) { HTM <- HT/100; WCM <- WC/100; BMI <- WT/(HTM^2); list(BMI=BMI, ABSI=WCM/(BMI^(2/3)*sqrt(HTM))) }とでも関数定義しておけば,例えば,身長160cm,体重55kg,腹囲70cmの人なら,ABSI(160, 55, 70)と打つだけでBMIとともにABSIも計算される。NHANESの平均レベルだと,20歳前後では男女とも0.078程度,80歳前後では男性で0.088程度,女性で0.084程度というグラフが掲載されているが,腹部肥満を示すカットオフ値はこの論文には掲載されていない。ちなみに,さっきのコードでABSI()と打つと,身長170cm,体重80kg,腹囲88cmの人(誰の値かは敢えて言うまい)のBMIが27.68,ABSIが0.074とわかる。日本のBMIの基準値では肥満に分類され,特定健診でも警告される値だが,最近のメタアナリシスでは最も死亡リスクが低い範囲だし,ABSIは米国NHANESの平均レベルよりずっと小さい。ハイリスクアプローチとしては完全に破綻している(ことを多くの公衆衛生学者が指摘しているのに一向に基準値が変わらない。内科系9学会の面子を守るためではないかと邪推してしまうほどおかしい)特定健診への切り込み口としては,この辺から行くのがいいかもしれない。
- 羊土社『実験医学』2013年12月号を書店店頭(というか,名谷キャンパスの生協の書籍売り場)でみかけ,特集感染症の目次があまりに魅力的なので衝動買いした。時間がないので,まだWHOの進藤さんの寄稿と,マラリアワクチンの話と,マダニが媒介する新興感染症SFTSの記事しか読んでいないが,他も面白そうだ。
- 環境省のtweetで,「COP19の結果概要と評価を掲載しました。COP21におけるすべての国が参加する将来枠組みの合意に向けた準備を整えるという我が国の目標を達成することができました。」とあった。後で読もう。
- vaio-saのハードディスクは,Seagateの8GB-SSDキャッシュと750GB-HDDのハイブリッドドライブに換装してあるのだが,何でもかんでも入れてあるため,残容量がかなり減ってきた。次に換装するなら1TBかなあと思っていたが,PC Watchの記事によると,Western Digitalが,通常のSATAで利用可能な,2.5インチ筐体に128GB-SSDと1TB-HDDを収めた世界初のデュアルドライブ「WD Black2」を発表したそうだ。レビュー記事によると,ちょっとセッティングが面倒そうだが,ノートPCのHDD換装には魅力的なドライブだと思う。ちょっとまだ値段が高すぎるが。
- 20:08に研究室を出て,直通終バスで帰宅。『ミス・パイロット』を見ながら,新タマネギ,ジャガイモ,葉っぱ付きのカブ,ナス,ベーコンを煮込んだ野菜スープを作り,晩飯。
- 昼間返事した日付変換だが,Rで全部やるには以下。
- 変数BDとDDに出生年月日,死亡年月日の7桁数字がそれぞれ入っているとします。
- ADY <- c(1867,1911,1925,1988)として,元号に合わせて足す西暦数字を定義したベクトルを用意します。
- dd <- function(X) {as.vector(ISOdate((ADY[X %/% 1000000]+((X %% 1000000) %/% 10000)),((X %% 10000) %/% 100),(X %% 100)))}と関数定義します。
- LY <- (dd(DD)-dd(BD))/365.24とすれば,LYには生存年数が入ります。数字が日付として扱える7桁でないとNAになります(ただし,2231211のように,その元号にはない年次が入っていてもエラーにはならず,この場合だと西暦1934年として扱われます)。
- 人口学会から届いた仕事を1つ済ませてから眠った。
△Read/Write COMMENTS
▼前【526】(講義2つ,院生の論文添削,ゼミの合間を縫って締め切り原稿(2013年11月25日)
) ▲次【528】(今日も公務1つの他は締め切りと講義準備(2013年11月27日)
) ●Top
Notice to cite or link here | [TOP PAGE]