2017年9月30日 星期六

間歇生酮飲食的效果比較好

這個月的 Cell Metabolism 刊了兩篇最近台灣很夯的話題:生酮飲食。

先介紹一下身體的能量轉化過程。通常碳水化合物被吃進去後,會被分解成葡萄糖,進入血液中,然後送到身體各部位,在細胞中轉化為能量 ATP。當年大學生化必背的葡萄糖 glycolysis,和必考的一個 glucose 可以轉化成多少個 ATP。除了葡萄糖外還有脂肪也是能量來源之一,有必背的 Creb Cycle (Citric Acid Cycle, CAC),還有一圈下來會產生幾個 NADH。



酮體(ketoone bodies)是脂肪酸的產物,包括有 acetoacetate, acetone 和 β-hydroxybutyrate,主要在肝臟生成(圖四)。這幾個 cycle 的關鍵點是 acetyl-CoA,當 acetyl-CoA 堆積太多來不及消耗的時候,就會轉成 ketone bodies,然後在飢餓、葡萄糖不夠用的時候,ketone bodies 就會從肝臟被運送到身體其他部位讓 CAC 得以繼續進行。以上所有 pathways 和 cycles 都是大學時生化課必背的東西,現在都忘了差不多惹,只好把課本拿出來翻一下。QQ



生酮飲食的目的是希望把醣降低到讓人體不得不把脂肪轉化成 ketone bodies 後,送出去給身體其他部位用。通常生酮飲食是指脂肪對碳水化合物和蛋白質的比例,嚴格一點的是 4:1 (4g fat to 1g carb/protein),再來是 3:1 和 2:1,通常碳水化合物會控制在 20g - 50g。為了不讓碳水化合物過量,會變成大大減少纖維質和其他維他命的攝取,因此生酮飲食必須要被謹慎監控。而食物裡各個含量的比例也要算好,才能讓肝臟持續地製造 ketone bodies,使身體用到脂肪而不是醣類。

兩篇的其中一篇研究是 UC Davis School of Veterinary Medicine 做的,之前有研究顯示顯示低卡飲食可以減緩老化現象,這篇研究的其中一位作者、同時也是位營養師的 Jon Ramsey 想知道高脂飲食是否對老化有影響。他們把老鼠分成三組,每組吃的熱量都相同,分別吃正常的高醣飲食(65% 的卡路里來自碳水化合物, 18% 蛋白質, 17% 脂肪)、低醣高脂飲食(low-carb diet, LCD, 70% 卡路里來自脂肪, 10% 碳水化合物, 20% 蛋白質),或生酮飲食(ketogenic diet, LD, 89% 卡路里來自脂肪, 10% 蛋白質, < 1% 碳水化合物)。每組老鼠從十二個月大開始控制飲食,然後各組又再分成兩組,一組吃一個月,另一組吃 14 個月。結果生酮飲食(KD)的老鼠比正常高醣飲食(控制組)的壽命長了 13.6%,LCD 飲食的老鼠壽命介於 KD 和正常飲食老鼠之間,三組的平均壽命分別為 886 天(控制組)、943 天(LCD)和 1003天(KD)。另外,在老鼠吃了一至 14 個月的飲食後(也就是 13 個月到 26 個月大的時候),測驗他們的認知能力和體能,發現 KD 飲食的老鼠記憶力維持得比正常飲食和 LCD 飲食的好,吃了十四個月 KD 飲食的老鼠的體能也比吃正常飲食的老鼠好,而吃 LCD 飲食的老鼠的表現則大多介於正常飲食的和 KD 飲食的之間。

在體重的部分,LCD 飲食的老鼠比控制組老鼠和 KD 飲食的老鼠種。身體比重部分,正常老鼠和 LCD 老鼠的瘦肉(lean mass)比例隨著年齡的增加,但在 26 個月大的時候,其瘦肉比例比 KD 飲食的老鼠低。LCD 飲食的老鼠,其脂肪比例比正常飲食和 KD 飲食的老鼠都多,三組老鼠的脂肪比例皆在 17 個月大的時候達到最高峰。

在吃了一個月和 14 個月後的時候,他們測了餐後山小時血中的生酮(β-hydroxybutyrate)含量,一個月的時候,KD 組的生酮量比另外兩組都高很多,在吃了十四個月後,控制組和 LCD 組的血中生酮量有變高一點,KD 組的跟吃一個月後的一樣高,但還是比另外兩組都要高。KD 組和 LCD 組的血中 triglycerides 含量在十四個月的飲食後比控制組高,LCD 組的自由脂肪酸(free fatty acid)比控制組和 KD 組高。KD 組的總膽固醇和 HDL 比控制組和 LCD 組高,控制組的 LDL 則比 LCD 組和 KD 組的高。另外,吃了一個月生酮飲食的老鼠的 glucose tolerance 比其他組差。

好奇看了老鼠的生酮飲食到底是吃什麼,結果食物脂肪來源是大豆油(soybean oil)和豬油(lard),老鼠能這樣連吃十四個月,人類無法吧?!

第二篇研究則是 UCSD 和 Buck Institute for Research on Aging 的 Eric Verdin 實驗室做的。之前小型的人類認知研究顯示 β-hydroxybutyrate (BHB) 可以改善記憶力,Verdin 認為 BHB 可能有增進記憶力之外的好處,他們希望找到一個不用節食,也可以利用 BHB 的方法。生酮飲食是除了節食和運動外,讓身體可以持續生產 BHB 的方法之一,因此這個研究的第一作者 John Newman 想要知道長期生酮飲食的影響,他說飲食的設計很重要,需要注意到任何細節,他想要一個讓不適感降到最低但又能讓身體製造最大量 BHB 的食譜。

他們先試了碳水化合物比例不同的食譜,發現零碳水化合物的飲食會讓血中的 BHB 濃度達到最高,隨著碳水化合物的量增加,血中 BHB 的濃度會跟著減少,15% 的碳水化合物是最低點(也就是 baseline),高於 15% 碳水化合物的飲食的話,血中的 BHB 濃度還是會維持在 baseline。接下來的實驗他決定用這三種飲食比例:正常的高碳水化合物飲食(控制組, 77% carb, 15% fat, 10% protein),零碳水化合物的生酮飲食(ketogenic diet, KD, 0% carb, 90% fat, 10% protein),和高脂肪低碳毀化合物(非生酮)飲食(high-fat, non-ketogenic diet, HF, 15% carb, 75% fat, 10% protein)。另外在 KD 和 HF 這兩組,他們試了兩種吃法:每天吃和正常飲食每週輪流吃(Cyclic KD, Cyclic HF)(也就是一週吃 KD 或 HF,一週正常飲食這樣輪流)。

* 注意:三種飲食的蛋白質含量都是 10%。

結果發現,HF 飲食的老鼠血中 BHB 的含量和正常飲食一樣,不過所用的能量來源仍是脂肪。另外,每天吃 KD 或 HF 的話是會胖的,但是和正常飲食輪流吃的話,體重則會維持正常。生酮飲食後的血中 BHB 含量和節食後的濃度是一樣的(1-2mM),而當和正常飲食輪流吃的話,血中 BHB 的濃度會比一直持續吃生酮飲食的來得高。基於這些結果,他們決定了五種飲食方式讓老鼠從十二個月大的時候開始吃,然後研究這五種飲食方式對壽命和健康等等的影響。

五種分別為:
- 持續只吃正常飲食
- 持續只吃 KD
- 持續只吃 HF
- Cyclic KD (weekly)
- Cyclic HF (weekly)

結果發現 KD 和 HF 組的老鼠體重比其他三組重很多,Cyclic HF 組的體重比正常飲食(控制組)和 Cyclic KD 高一點,Cyclin KD 和正常飲食的體重差不多。在壽命的部分,Cyclic KD 和 Cyclic HF 的早死率比控制組低,平均壽命也比較長,但是這三組的最長壽命都差不多,表示 Cyclic KD 和 Cyclic HF 並沒有增長老鼠的壽命,但是使老鼠活超過 30 個月的比例增高。有趣的是只吃 KD 和 HF 的老鼠都比較肥胖且早死。他們比較了正常飲食老鼠和 Cyclic KD 老鼠在中年(一歲)和老年(兩歲和兩歲半)時的體力和記憶力,發現 Cyclic KD 組老鼠老年時的體力和記憶力退化的比較慢,也比正常飲食的老鼠好,而正常飲食的老鼠,其記憶力則顯現出老化的情形。

他們同時也測了血液中的 BHB 濃度,KD 飲食可以增加血中 BHB 濃度,但是 HF 飲食沒有增老鼠血中的 BHD。當老鼠停止生酮飲食幾個月後,血中不再有 BHB 後再做一次記憶力測驗,他們的表現一樣好,表示生酮飲食的影響是持續性的,即使停了以後仍能維持。

Verdin 說目前生酮飲食被用來治療癲癇(epilepsy),如果正常人想進行這類飲食,應該要先諮詢過專家的意見,另外運動也會產生 ketone bodies,也許這也是為什麼運動對大腦和身體有益的原因。



Articles:

MedicalXpress / What are ketogenic diets? Can they treat epilepsy and brain cancer? (2017)

MedicalXpress / Eat fat, live longer? Mouse study shows a high fat diet increases longevity, strength (2017)

MedicalXpress / Ketogenic diet improves healthspan and memory in aging mice (2017)


Papers:

MN Roberts et al, A Ketogenic Diet Extends Longevity and Healthspan in Adult Mice. Cell Metabolism (2017)

JC Newman et al, Ketogenic Diet Reduces Midlife Mortality and Improves Memory in Aging Mice. Cell Metabolism (2017)









2017年9月24日 星期日

Python | 我想玩,但要怎麼開始?

拖了好久的 Python,上課好像已經是半年前的事惹哈哈。其實 Python 的語法和 R 差不多,所以你會 R 的話基本上可以互用,只是兩者的介面不一樣。

課程是建議安裝 Python version 3.x,可以在 Anaconda 網頁下載(點此),我那時下載以為會是像 RStudio 那樣,是一整個 Python 環境,可以在裡面做任何事,不過上課後發現不是那樣,哈哈。

如果是用 MacBook 的話,要先叫出 Terminal,然後 command 打入:jupyter notebook。

之後會出現這樣的畫面(點圖可放大):

點圖變大

對,它看起來會像是變成瀏覽器的一個頁面,上面出現的是你電腦裡的主要 folders,Python script 的檔案也可以在正常的 folder 裡看到,不用進入 Python 的環境,只是要打開的話需要進入 jupyter notebook。

如果想要在 jupyter 裡面看電腦裡面有哪些 folders,或是 folders 裡面有哪些 sub-folders 的話,用的指令是跟 bash shell 相同的,例如用 ls 列出有什麼檔案,用 cd 進入你想進的 folder。



這裡就不再重複 Bash Shell 的指令,細節請看這篇:Bash Shell

你可以用 bash shell 的指令在你要的 folder 建立新的 folder 或檔案,也可以直接在正常的 folder 開新的 folder。進入到你想開新 python 檔案的資料夾後,要開始寫一個新的 script 的話就在右上角的 "New" 那裡打開一個新的檔案:Python [conda root]。

點圖變大

打開之後就會出現這樣的頁面,input (In[]) 欄讓你打指令,就像 R 裡面的 console,然後按 Enter 可以換行,如果要讓它跑結果,就是按 "Shift + Enter"。指令是可以更改的,用滑鼠點到那一欄以後就可以改,不用再開另一欄重打,改過的指令再按一次 "Shift + Enter" 會出現新的計算結果。

點圖變大

跟 R 同樣有分三種:string (字), integer (整數), float (有小數點的)

在數字外加 '' 就會把數字變成 string,例如 '8' 是個 string 而不是數字。不同的種類不能互相加減,要把它轉成同種,例如上面的 a 是 string,乘以十的話就會出現十個 a,也就是十個 hello。String 不能和數字相加減,上面的例子是把 b 變成 string,兩個 string 相加就會變成 hello10。把整數的 b 變成有小數點的 float 就可以和 c 相加,結果就變成 10.0 + 6.6 = 16.6。

要載入 packages 的話,要用 import 這個指令。例如要讀 csv file 的話,需要用 read_csv() 這個功能,而這個功能在 package pandas 裡面,我們需要先 import pandas,指令就是:

import pandas

例如要讀取的檔案為 apple.csv,先把檔案設成一個 data frame,把其命名為 data_apple。

data_apple = pandas.read_csv('apple.csv')

如果覺得每次要用 read_csv() 這個功能要打很長很煩的話,可以把 pandas 指定一個短的代替,例如 pd,這時在 import 的時候就要下這樣的指令:

import pandas as pd

之後使用的時候就可以變成:

data_apple = pd.read_csv('apple.csv')

這篇就先介紹到這,只是個入門讓大家知道怎麼開始,其他語法很多都和 R 一樣,大家可以互相轉換來試試看。









2017年9月23日 星期六

關於中風的小常識

中風有兩種:出血性(hemorrhagic)和缺血性(ischemic)

大部分(~80%)的中風都是 ischemic,這種中風是因為血管阻塞,導致血液無法進入腦部造成的,大腦是用電量最多的器官,就是要耗掉最多養分和能量的器官,養分和氧氣是靠血液運送到大腦的,所以只要缺血幾秒鐘就可以死掉很多腦細胞(1.9 million brain cells/minute)。阻塞血管的東西就是血塊(clot),血塊的來源有兩種,一種是腦內血管裡自己堆積的血塊,這種造成的 ischemia 叫做 thrombosis。如果血塊是在其他地方堆積出來的,隨著血液流啊流的,流到靠近腦部的動脈時卡住了,結果把動脈堵住使得血液無法進入腦部,這種造成的 ischemia 叫做 embolism。目前中風的急救方式是用 tPA (thrombolytic agent tissue plasminogen activator) 來溶解血栓,中風後的四個小時內是急救黃金時間,中風後一小時內治療可救到的腦細胞有 70%,兩小時內 40%,三小時只能救到 20%,但很常發生的情況是中風發生後,有人發現、到送到醫院,確定是哪種中風(出血或是缺血)的這段時間已經超過四個小時了。

如果把腦部切開來看,缺血最多的地方就是中風的中心,叫 ischemic core,會看到那區變成白白的(見下圖),叫 infarct area (infarction),這區的細胞死亡是不可挽回的。中心的周邊區域叫 penumbra,或是 peri-infarct zone,這區的血流量也不足,但如果及時讓血液回流可以讓細胞不再繼續死亡,目前研究的治療方式主要是針對這區,希望能在 penumbra 的細胞死亡之前讓其恢復功能。

Ischemic stroke 又分兩種,一種是暫時性的 transient ischemic stroke (TIA, transient ischemic attack),又叫小中風(mini-stroke),這種大概只有幾分鐘,通常一小時內血管就會恢復流通,血液會再次進入到腦中(reperfusion),所以很少會死到腦細胞造成 infarction。雖然是暫時性的,但是通常發生後會再發生,再次發生就會變成是嚴重的中風,也就是另外一種:acute ischemic stroke,所以不要輕忽 TIA。

Acute ischemic stroke 則是永久性的,會造成白白的 infarct area,出現的症狀不像 TIA 通常會在一個小時後消失,會造成之後身體行動上的不便,需要靠復健來恢復,因為已經傷到腦部了,所以也可能會在認知能力上或記憶力上造成影響。


Figure / 圖片中的 MCAO (middle cerebral artery occlusion)是研究上常用的 stroke model,用手術造成大腦中動脈堵塞,使老鼠產生中風的現象。白色的 infarct area 在右腦,會出現左半邊身體痲痹的情形,可以用來確認 MCAO 手術是否成功。(A Popp et al, PLOS ONE 2009)

圖中左邊是指 occlusion 的時間,分別是半小時和兩小時,上面則是 reperfusion 的時間。舉例來說,左上角那個腦是 occlusion 半小時後 reperfusion 兩小時,也就是用手術線堵住動脈血管半小時後,把手術線抽出讓血液回流兩個小時。我們通常是做一個小時的 occlusion,再取不同的 reperfusion 時間點。一個小時的 occlusion,之後三個小時的 reperfusion,可以看到老鼠有半邊身體不協調,切開腦部看,有時已可看到一點 infarction,通常在 24 小時後看的話就會看到明顯的 infarction。

如果想看 MCAO 手術是怎麼做的,可以看這個影片:Mouse Model of Middle Cerebral Artery Occlusion


中風後細胞內發生什麼事?

血管阻塞造成缺氧缺血的情況發生後的初期,除了細胞能源 ATP 不足,啟動無氧醣解反應(anaerobic glycolysis ),使得酸鹼值降到 pH 6.4-6.7,導致細胞酸化(acidosis)外,細胞也會釋放出大量的穀胺酸(glutamate)。穀氨酸是神經傳導物質,過量的穀氨酸會啟動神經細胞接受器 NMDARs 和 AMPARs,造成大量鈣離子流入細胞內,粒線體和 ER 裡儲存的鈣離子也會被釋放出來,使得細胞內鈣離子濃度過高,活化細胞內的一些酵素(Ca2+-dependent enzymes),例如 neuronal NOS (NO synthase),生產 NO 和 superoxide (H2O2),引發了下游的死亡訊號(cell death signalling),這種因為穀氨酸刺激造成的死亡稱為 excitotoxicity。除了鈣離子濃度上升會活化很多酵素,啟動下游訊號外,細胞的酸化反應會活化一個酸性感應蛋白 ASIC1a (acid-sensing ion channels),ASIC1a 活化後會使更多鈣離子流進細胞內,使整個情況更惡化。除此之外,粒線體吸收細胞內鈣離子讓濃度達成平衡,但也使粒線體本身因此製造 ROS,造成 mitochondrial depolarization,引發細胞死亡。


其實還有很多是目前還不清楚的,上面就先簡單介紹到這邊吧。

關於穀氨酸和 excitotoxicity 可以看這篇:關於 glutamate 的小知識









2017年9月15日 星期五

關於 glutamate 的小知識

有學過生物的應該都知道二十種氨基酸裡有一個是 glutamate,中文叫做穀氨酸。其實穀氨酸除了是(非必需)氨基酸的一種外,它還是大腦裡最多的神經傳導物質(neurotransmitter),它在腦內的神經接受器是 NMDA receptors (NMDARs),當它和 NMDARs 接合後會使其打開,讓鈣離子(Ca2+)進入細胞內。穀氨酸在正常的生理狀態下是無害的,但是過多的時候會造成大量鈣離子進入細胞內,鈣離子會啟動不同的訊息傳遞,造成細胞死亡。因為過多穀氨酸打開 NMDARs,造成大量鈣離子進入細胞內而導致的神經細胞死亡,叫做 excitotoxicity。

在穀氨酸刺激造成細胞死亡的過程裡,鈣離子扮演著重要的角色。給予神經細胞穀氨酸後,會先造成細胞漲大(neuronal swelling),24 小時後細胞才死亡的情況,稱為 delayed cell death。在沒有大量穀氨酸的情況下,高濃度的鉀離子(K+)同樣會造成 neuronal swelling。如果把鈉離子(Na+)拿掉,那在穀氨酸刺激後不會產生 neuronal swelling,但是 24 小時後細胞仍會死亡。若是拿掉鈣離子(Ca2+),穀氨酸刺激雖然會加劇 neuronal swelling 的情況,但是會阻止 24 小時候 delayed cell death 的發生,而因為刺激引起細胞狀態上的改變,例如 neuronal swelling 會隨著時間漸漸復原。

什麼樣的狀況下會造成 excitotoxicity 呢?當腦部受創時,例如外傷性腦損傷(traumatic brain injury, TBI)和中風,就會出現 excitotoxicity 的情形。中風時,在缺氧缺血的情況下,腦內的神經細胞會釋放出大量的穀氨酸,同時也會使得負責輸送細胞內外離子的蛋白質失調,造成細胞內外正負離子不平衡、細胞膜去極化(depolarization)。在穀氨酸啟動 NMDARs 和細胞膜去極化的情況下,大量的鈣離子會通過 NMDARs 進入細胞內,引發細胞的死亡反應。目前研究治療中風的其中一個方向,即是抑制 NMDARs。


Figure / JW Olney, Annu Rev Pharm Toxicol 1990 (doi: 10.1146/annurev.pa.30.040190.000403)

穀氨酸是怎麼被發現是 neurotoxic,會造成神經細胞死亡的呢?L-glutamic acid 和其鈉鹽(monosodium glutamate (MSG), 穀氨酸鈉)本來是用來治療癲癇的小發作(petit mal)和心理疾病,後來在 1957 年的時候,D.R. Lucas 和 J.P. Newhouse 發現餵食幼鼠穀氨酸鈉會使牠的視網膜神經細胞死亡,成年老鼠長期每天食用 40mg (1.0-1.5mg/g) 的量則無影響 [1]。之後華盛頓大學的 J.W. Olney 發現穀氨酸不只會使幼鼠的視網膜細胞死亡,也會使大腦其他部位的神經細胞死亡,例如腦下視丘(hypothalamus),而成年老鼠在被施打高劑量(5-7mg/g)穀氨酸鈉的情況下也會出現神經細胞死亡的狀況 [2]。除了穀氨酸(和 glutamic acid)外,其他會刺激神經細胞的氨基酸也有同樣的影響,例如 L-aspartate, L-cysteine [3, 4]。另外,高量的穀氨酸鈉也會造成內分泌失調,在出生後一到十天每天的被施打穀氨酸鈉的幼鼠,在一個月到五個月大的期間明顯比正常老鼠肥胖 [2]。

其實呢,大家可能已經知道了,穀氨酸鈉就是味精,這些研究也因此引起了幼兒食品中若含有 MSG 是否會影響幼兒腦部發展的疑慮。不過呢,對成年人來說應該並沒有什麼影響,除非你吃很多。是說有些人還是對味精比較敏感的,所以才會有 Chinese Restaurant Syndrome,就是指去中國餐館吃了以後出現的不適症狀,因為中國餐館的菜都加了很多味精調味。



References

1. DR Lucas & JP Newhouse, The Toxic Effect of Sodium L-Glutamate on the Inner Layers of the Retina. AMA Arch Ophtalmol (1957)

2. JW Olney, Brain Lesions, Obesity, and Other Disturbances in Mice Treated with Monosodium Glutamate. Science (1969)

3. JW Olney and O Ho, Brain Damage in Infant Mice following Oral Intake of Glutamate, Aspartate or Cysteine. Nature (1970)

4. JW Olney et al, Cytotoxic Effects of Acidic and Sulphur Containing Amino Acids on the Infant Mouse Central Nervous System. Exp Brain Res (1971)









2017年9月13日 星期三

R | Calculate row means, SD and SE

明明有 Excel 可用為什麼偏要用 R?
之 《 為了要畫出圖,只好先從最基本的開始研究。QQ 》

・如何 merge 兩個檔案資料(dataframe)
・如何從檔案資料中的某變項(variable)中挑出你要的
・如何從資料中指定出一個 matrix
・如何算每個 row 的平均值, standard deviation (SD) 和 standard error (SE)

我們需要裝下面的幾個,其中的 matrixStats 是用來算 mean 和 SD 的。

library(dplyr)
library(data.table)
library(tidyverse)
library(matrixStats)

Define a data frame, df1
Use data.frame() function to create a data frame

ID <- c("A", "B", "C", "D", "E", "F", "G")
N1 <- c(2,2.6,4,5,8,10,9)
N2 <- c(3,2.8,5,6,6,7,8)
N3 <- c(2,3.6,3,6,6,10,7)
df1 <- data.frame(ID, N1, N2, N3)

   ID  N1  N2   N3
1  A  2.0 3.0  2.0
2  B  2.6 2.8  3.6
3  C  4.0 5.0  3.0
4  D  5.0 6.0  6.0
5  E  8.0 6.0  6.0
6  F 10.0 7.0 10.0
7  G  9.0 8.0  7.0

Define another data frame, df2

P1 <- c(5,3.8,2,5,10,7,8)
P2 <- c(3,2.6,6,7,6,8,9)
P3 <- c(3,4.8,6,7,8,7,10)
df2 <- data.frame(ID, P1, P2, P3)

  ID   P1  P2   P3
1  A  5.0 3.0  3.0
2  B  3.8 2.6  4.8
3  C  2.0 6.0  6.0
4  D  5.0 7.0  7.0
5  E 10.0 6.0  8.0
6  F  7.0 8.0  7.0
7  G  8.0 9.0 10.0

設定第三個檔案資料,其中有兩個變項(variables)裡面的資料不是數字,而是字(character)。

K1 <- c(2,5,7,6,7,9,8)
K2 <- c(6,2,5,7,6,10,8)
K3 <- c("2","5","6","5","8","9","7")
Day <- c("AM", "PM", "PM", "AM", "PM", "AM", "AM")
df3 <- data.frame(ID, K1, K2, K3, Day)

   ID K1 K2 K3 Day
1  A  2  6  2  AM
2  B  5  2  5  PM
3  C  7  5  6  PM
4  D  6  7  5  AM
5  E  7  6  8  PM
6  F  9 10  9  AM
7  G  8  8  7  AM

Combine 2 data frames by the variable "ID"
Need a common variable between 2 data frames
要合併兩個資料需要有一個共同的 variable,在這個例子裡是 ID。

Use merge() function to combine the 2 data frames

total_df <- merge(df1, df2, by = "ID")

  ID   N1  N2   N3   P1  P2   P3
1  A  2.0 3.0  2.0  5.0 3.0  3.0
2  B  2.6 2.8  3.6  3.8 2.6  4.8
3  C  4.0 5.0  3.0  2.0 6.0  6.0
4  D  5.0 6.0  6.0  5.0 7.0  7.0
5  E  8.0 6.0  6.0 10.0 6.0  8.0
6  F 10.0 7.0 10.0  7.0 8.0  7.0
7  G  9.0 8.0  7.0  8.0 9.0 10.0

另外一個合併資料庫的語法是 cbind(),但這個是把第二個資料直接接在後面,所以兩個資料檔不需要有同樣一個變項,也就是不用跟 merge() 需要用 "ID" 來合併。因此,如果用 cbind() 來合併 df1 和 df2 的話,就會顯示有兩欄是 "ID。

total_df2 <- cbind(df1, df2)

  ID   N1  N2   N3 ID   P1  P2   P3
1  A  2.0 3.0  2.0  A  5.0 3.0  3.0
2  B  2.6 2.8  3.6  B  3.8 2.6  4.8
3  C  4.0 5.0  3.0  C  2.0 6.0  6.0
4  D  5.0 6.0  6.0  D  5.0 7.0  7.0
5  E  8.0 6.0  6.0  E 10.0 6.0  8.0
6  F 10.0 7.0 10.0  F  7.0 8.0  7.0
7  G  9.0 8.0  7.0  G  8.0 9.0 10.0

如果想用 cbind() 把兩個檔案合併成 total_df 的樣子,需要把 df2 的 ID 那欄先拿掉。

接下來,要介紹兩種使用這種資料檔案的方法。

1. 從檔案資料裡面挑出你要的。之前已經介紹 filter(),是從檔案裡面挑出你要的 variables,這裡想介紹的是在你想要的 variables 挑出你要的部分,用的語法是: var %in% c(" ") 

%in% 是指在某個 variable 裡面找出符合 c(" ") 裡面所述的條件的。

filter() 的用法請看這篇:R | Data manipulation

下面介紹要怎麼用。我們現在把三個檔案資料合併在一起。

total_df3 <- merge(total_df, df3, by = "ID")

>total_df3
   ID   N1  N2   N3   P1  P2   P3 K1 K2 K3 Day
1  A  2.0 3.0  2.0  5.0 3.0  3.0  2  6  2  AM
2  B  2.6 2.8  3.6  3.8 2.6  4.8  5  2  5  PM
3  C  4.0 5.0  3.0  2.0 6.0  6.0  7  5  6  PM
4  D  5.0 6.0  6.0  5.0 7.0  7.0  6  7  5  AM
5  E  8.0 6.0  6.0 10.0 6.0  8.0  7  6  8  PM
6  F 10.0 7.0 10.0  7.0 8.0  7.0  9 10  9  AM
7  G  9.0 8.0  7.0  8.0 9.0 10.0  8  8  7  AM

如果想從 total_df3 裡面挑出 Day 是 "AM" 的 ID,就會是這樣:Day %in% c("AM")

t1 <- filter(total_df3, Day %in% c("AM"))

>t1
  ID N1 N2 N3 P1 P2 P3 K1 K2 K3 Day
1  A  2  3  2  5  3  3  2  6  2  AM
2  D  5  6  6  5  7  7  6  7  5  AM
3  F 10  7 10  7  8  7  9 10  9  AM
4  G  9  8  7  8  9 10  8  8  7  AM

c(" ") 不一定要是字,也可以是數字,也可以在變項裡選兩個以上你想要的,例如想從 K2 裡面挑出 2, 6 和 10。

t2 <- filter(total_df3, K3 %in% c("2","6","10"))

>t2
  ID   N1  N2   N3   P1  P2  P3 K1 K2 K3 Day
1  A  2.0 3.0  2.0  5.0 3.0 3.0  2  6  2  AM
2  B  2.6 2.8  3.6  3.8 2.6 4.8  5  2  5  PM
3  E  8.0 6.0  6.0 10.0 6.0 8.0  7  6  8  PM
4  F 10.0 7.0 10.0  7.0 8.0 7.0  9 10  9  AM

我們也可以同時設兩種條件,例如要 K2 是 6 或者 Day 是 AM 的,用的符號是  |

t3 <-  filter(total_df3, K2 == 6 | Day %in% c("AM"))

>t3
   ID N1 N2 N3 P1 P2 P3 K1 K2 K3 Day
1  A  2  3  2  5  3  3  2  6  2  AM
2  D  5  6  6  5  7  7  6  7  5  AM
3  E  8  6  6 10  6  8  7  6  8  PM
4  F 10  7 10  7  8  7  9 10  9  AM
5  G  9  8  7  8  9 10  8  8  7  AM


2. 算出每行的的 mean 和 SD (standard deviation)。

Calculate mean of each row (= rmeans)
Use mutate() function to assign a new variable
Use rowMeans() function to calculate means

在下面的語法中,我們指定 rmeans 為每行的 mean,然後用 rowMeans() 的功能算出來,再用 mutate() 把它變成一個新的 variable 放在表格的最後一欄。

total_RM <- total_df %>%
  mutate(rmeans = rowMeans(total_df[,2:7])) %>%
  as.data.frame %>%
  print()

  ID   N1  N2   N3   P1  P2   P3   rmeans
1  A  2.0 3.0  2.0  5.0 3.0  3.0 3.000000
2  B  2.6 2.8  3.6  3.8 2.6  4.8 3.366667
3  C  4.0 5.0  3.0  2.0 6.0  6.0 4.333333
4  D  5.0 6.0  6.0  5.0 7.0  7.0 6.000000
5  E  8.0 6.0  6.0 10.0 6.0  8.0 7.333333
6  F 10.0 7.0 10.0  7.0 8.0  7.0 8.166667
7  G  9.0 8.0  7.0  8.0 9.0 10.0 8.500000

上面的  total_df[, 2:7]  是指在 total_df 裡面的第二到第七欄,也就是算出每行第二到第七欄的 mean。(如果你還記得第一篇的基本語法的話, [ , ]  裡面是  [row, col] 。)

因為可以指定要算哪幾欄的 mean,所以我們也可以算 total_df3 的,只要不要把最後是 character 的那兩欄算進去就好了,也就是算出 N1 到 K2 這幾欄的 mean。

total_RM <- total_df3 %>%
  mutate(rmeans = rowMeans(total_df3[,2:9])) %>%
  as.data.frame %>%
  print()

  ID   N1  N2   N3   P1  P2   P3 K1 K2 K3 Day rmeans
1  A  2.0 3.0  2.0  5.0 3.0  3.0  2  6  2  AM  3.250
2  B  2.6 2.8  3.6  3.8 2.6  4.8  5  2  5  PM  3.400
3  C  4.0 5.0  3.0  2.0 6.0  6.0  7  5  6  PM  4.750
4  D  5.0 6.0  6.0  5.0 7.0  7.0  6  7  5  AM  6.125
5  E  8.0 6.0  6.0 10.0 6.0  8.0  7  6  8  PM  7.125
6  F 10.0 7.0 10.0  7.0 8.0  7.0  9 10  9  AM  8.500
7  G  9.0 8.0  7.0  8.0 9.0 10.0  8  8  7  AM  8.375

*關於 mutate() 和 %>% 的用法可以參考:這篇

Define a matrix, m1 (要算出 standard deviation,需要讓 dataframe 變成 matrix。)
Use as.matrix() function to assign/create a matrix

as.matrix() 的功能把資料檔案變成一個 matrix。

m1 <- as.matrix(total_df[,2:7])

       N1  N2   N3   P1  P2   P3
[1,]  2.0 3.0  2.0  5.0 3.0  3.0
[2,]  2.6 2.8  3.6  3.8 2.6  4.8
[3,]  4.0 5.0  3.0  2.0 6.0  6.0
[4,]  5.0 6.0  6.0  5.0 7.0  7.0
[5,]  8.0 6.0  6.0 10.0 6.0  8.0
[6,] 10.0 7.0 10.0  7.0 8.0  7.0
[7,]  9.0 8.0  7.0  8.0 9.0 10.0

也可以把上面的 t3 設成一個 matrix,不過要注意一下,K3 裡面的是 character,如果也把它設進去,整個 matrix 裡的都會變成 character,所以這邊只能把 matrix 設到 K2,不包含 K3 這欄。

m2 <- as.matrix(t3[,2:9])

     N1 N2 N3 P1 P2 P3 K1 K2
[1,]  2  3  2  5  3  3  2  6
[2,]  5  6  6  5  7  7  6  7
[3,]  8  6  6 10  6  8  7  6
[4,] 10  7 10  7  8  7  9 10
[5,]  9  8  7  8  9 10  8  8

接下來,我們可以算 m1 和 m2 的 mean 和 SD。也就是說,你可以挑出你想要的資料算 mean 和 SD,在這個例子裡,就是 m2。

Calculate standard deviation (SD)
Use rowSds() function to calculate standard deviation of each row

算出每行的 SD:rowSds(matrix, na.rm = TRUE))

* setting na.rm = TRUE to omit NA(但在我們的 data frame 裡沒有 NA,所以沒差。)

transform(m1, SD = rowSds(m1, na.rm = TRUE))

transform() 的話,出來的結果會是一個表格,就是把 m1 加上算出來的 SD 合在一起變成一個新的表格的意思。

    N1  N2   N3   P1  P2   P3        SD
1  2.0 3.0  2.0  5.0 3.0  3.0 1.0954451
2  2.6 2.8  3.6  3.8 2.6  4.8 0.8710147
3  4.0 5.0  3.0  2.0 6.0  6.0 1.6329932
4  5.0 6.0  6.0  5.0 7.0  7.0 0.8944272
5  8.0 6.0  6.0 10.0 6.0  8.0 1.6329932
6 10.0 7.0 10.0  7.0 8.0  7.0 1.4719601
7  9.0 8.0  7.0  8.0 9.0 10.0 1.0488088

可以把新的表格指定為 m1_sd,像下面這樣:

m1_sd <- transform(m1, SD = rowSds(m1, na.rm = TRUE))

當你在 Console 打入 m1_sd 後就會出現上面的表格。

可以直接算出 SD,但是 output 只會出現數字,而不是一個表格,像下面這樣。

total_sd = rowSds(m1, na.rm = TRUE)

> total_sd
[1] 1.0954451 0.8710147 1.6329932 0.8944272 1.0954451

Calculate standard error (SE)

也可以算 SE,SE 的公式為:SD / sqrt (n)

n 為每個的樣本數(sample size),例如在 m1 中每個 ID (也就是每行)的樣本量有六個:N1, N2, N3, P1, P2, P3。

total_se = total_sd / sqrt(n)

Calculate standard deviation (sd) and standard error (se)
Create new variables "sd" and "se" and assign a data frame

如果我們想要算出 total_df 裡每行的 mean, SD 和 SE,然後用表格呈現出來,可以像下面這樣設。指定 rmeans 為每行 mean,sd 和 se 為其 SD 和 SE,語法上面已解釋過了,下面只是用 mutate() 的功能把它們變成新的 variables,然後呈現在最後三欄。

total_df_sum <- total_df %>%
  mutate(rmeans = rowMeans(total_df[, 2:7]),
         sd = rowSds(m1, na.rm = TRUE),
         se = sd / sqrt(6)) %>%
  as.data.frame()

  ID  N1  N2  N3  P1  P2  P3   rmeans        sd        se
1  A 2.0 3.0 2.0 5.0 3.0 3.0 3.000000 1.0954451 0.5477226
2  B 2.6 2.8 3.6 3.8 2.6 4.8 3.366667 0.8710147 0.4355074
3  C 4.0 5.0 3.0 2.0 6.0 6.0 4.333333 1.6329932 0.8164966
4  D 5.0 6.0 6.0 5.0 7.0 7.0 6.000000 0.8944272 0.4472136
5  E 8.0 6.0 6.0 8.0 6.0 8.0 7.000000 1.0954451 0.5477226

也可以只算你挑出的那幾個,例如 t3 中的那幾個 ID。

t3_sum <- t3 %>%
  mutate(rmeans = rowMeans(t3[,2:9]),
         sd = rowSds(m2, na.rm = TRUE),
         se = sd / sqrt(8)) %>%
  as.data.frame()


嗯,以上就先這樣吧。