網頁

2020年4月20日 星期一

R語言 Dataframe 操作

匯入 csv檔
假設有一學生成績資料 score.csv,用R語言匯入 csv檔:
score = read.csv("~/prog/r/score.csv", header=T, sep=",")
輸入 score 查看內容,共有5筆學生資料

增加一個欄位方式:
加上地理科成績,欄位名稱 S.Geography
score$S.Geography = c(78, 67, 89, 77, 86, 90)

計算並增加 Sum. 和 Avg. 欄位存放每個學生的成績總分和平均
sum_field = c()
avg_field = c()

for ( i in 1:nrow(score)) {  #nrow(score)取得score資料行數
    summary = sum(score[i, 3:5])
    sum_field[i] = summary
    avg = summary / 3
    avg_field[i] = round(avg, 2)   #浮點數取到小數點2位
}

score$Sum. <- sum_field
score$Avg. <- avg_field 


或是用 apply 會更簡單
score$Sum. <- apply(score[, 3:5], 1, sum)
score$Avg. <- round(apply(score[, 3:5], 1, mean), 2) 



刪除特定行的資料
例如要刪除學生 Chang 或 Lin 的資料
可以用 grep 找出符合條件的資料行
score[grep("Chang|Lin", score$Name), ]

要刪除只要前面加上"-"號即可
score[-grep("Chang|Lin", score$Name), ]

排序方式
依照學生成績總分排序(升序)
score[order(score$Sum), ]

依照學生成績總分排序(降序),只要加個 "-" 號就可以
score[order(-score$Sum), ]

最大值最小值
找出成績最好的資料和最差的資料:
score[which.max(score$Avg.[]), ]
score[which.min(score$Avg.[]), ]





2020年4月15日 星期三

使用 Notepad++ 讀取TSK log 檔案

前兩篇都是在 Linux環境下處理 TSK log 檔,這篇就用 windows 環境下的 Notepad++ 來處理
TSK log 檔,順便支持一下台灣人寫的非常棒的編輯器。
如果沒有 Notepad++ 請到 Notepad++ 下載處
https://notepad-plus-plus.org/downloads/v7.8.5/


1. 安裝好 Notepad++ 後開啟 log file

2. 你會看到資料都是連接在一起的,每個段落是用 NUL符 (ASCII 0) 連接,
 我們要做的就是將 NUL 換成換行符號即可。
 到 [搜尋] 功能下拉選單選擇 [取代]...

3. 接著在尋找內容欄位填入 \0,取代為欄位填入 \r
  搜尋模式選 [規則運算式],然後按下 [全部取代]

4. 瞬間就完成了,將轉換後的檔案另存心檔即可。簡單吧!

也可以將上述的動作存成巨集,下次只要執行巨集就好。


可以參考:
1. 使用 C 讀取TSK log 檔案
2. 使用 vim 讀取TSK log 檔案
3. 使用 Julia 讀取TSK log 檔案

2020年4月12日 星期日

使用 vim 讀取TSK log 檔案

上一篇介紹了用 C語言來讀取 TSK log 檔,這篇來講講使用 vim 編輯器直接使用搜尋/替換
的方式來轉換 log 檔。

1. 首先,用 vim 開啟 LOG_1.DAT 檔案:

2. 接著你會看到像下面的樣子,資料是用ASCII 0串在一起 (16進制 0x00):

 3. 先按ESC退出編輯模式,按下/\%x00
   說明: 第一個 "/"是搜尋,"\"跳脫下一個 "%","x00" 就是16進制 0

   然後按Enter 後你會看到有找到的字元都會被高亮起來,
   如果你的 vim 沒有高亮可以用 :set hlsearch 來設定。

4. 接著就將找到的這些字元替換成換行字元(\r)
 輸入 :%s/\%x00/\r/g
 說明: 搜尋/替換的格式為 %s/ 搜尋的字 / 替換的字 /g
 其中 s: search , g: global (全部的意思)

5. 如果沒輸入錯誤應該會看到如下的畫面,如果正確
  用 :w 檔名 ,另存新檔即可。

6. 按下 :q! 離開


2020年4月10日 星期五

使用 C 讀取TSK log 檔案

TSK的 log 檔案是一個 2進制檔,每筆紀錄用 0x00 當作結束,
總長度0x63FFF byte (409600 byte) 如下圖:


接下來就是如何用 C語言來讀取這個檔案,程式內容說明如下: 
首先是開啟檔案(fopen()),從標準輸入(ARGV)讀入檔名,
每次讀入1個字元(fgetc())直到檔案結束(EOF),
fp = fopen (argv[file_cont], "r");
while((ch = fgetc(fp)) != EOF) {
  printf("%c", ch = (ch == '\0') ? '\n' : ch);
}


其中,ch = (ch == '\0') ? '\n' : ch
這是三元運算子,等效是:
if (ch == '\0')
  ch = '\n';

意思是,如果讀入的字元是 '\0' 就更換成 '\n' (換行符),然後印出
寫成精簡一點就是:
printf("%c", ch = (ch == '\0') ? '\n' : ch);

因為這 log 檔通常是 3個,所以外層加上一個迴圈可以讓使用者輸入多個檔案
for (file_cont = 1; file_cont < argc; file_cont++) {
. . .
. . .
}
這樣我就可以同時輸入多個檔案依序讀取並印出:
$./log_prog  LOG_1.DAT  LOG_2_DAT  LOG_3.DAT

或是用shell的集合功能可以少打一些字:
$./log_prog  LOG_{1,2,3}.DAT
 
完整程式碼如下:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  FILE *fp;
  int file_cont;
  char ch;
  if (argc == 1)
    return 0;
  for (file_cont = 1; file_cont < argc; file_cont++) {
    printf("\n->>>>> File:%s <<<<<-\n", argv[file_cont]);
    fp = fopen (argv[file_cont], "r");
    while((ch = fgetc(fp)) != EOF)
      printf("%c", ch = (ch == '\0') ? '\n' : ch);

    printf("\n");
  }
  return 0;
}


輸出結果:


由於檔案很長所以可以利用導向符 ">" 輸出至檔案
$./log_prog  LOG_1.DAT  > log1.txt

這樣就可以用文字編輯器來開啟log1.txt



你可以參考:
1. 使用 Julia讀取TSK log檔案