Problem:
如何將資料為每列表示變數,每行表示一筆記錄資料轉換為每列表示記錄,每行表示變數之資料框(data.frame)物件,此功能類似 Excel \ 複製 \ 右鍵 \ 貼上選項 \ 轉置.感謝 R user - Hsieh 提供此問題
Analysis:
# 匯入資料 read.table 函數中,可以先設定 stringsAsFactors=FALSE, 如此所有資料可先保留字串資料型態> myData <- read.table("rowdata.csv", sep=",", stringsAsFactors=FALSE)
> myData
V1 V2 V3 V4 V5 V6
1 編號 1 2 3 4 5
2 型式 AAA AAA BBB BBB CCC
3 測量1 10 20 30 40 50
4 測量2 100 200 300 400 500
5 測量3 1000 2000 3000 4000 5000
6 結果 OK OK ERROR ERROR OK
> str(myData)
'data.frame': 6 obs. of 6 variables:
$ V1: chr "編號" "型式" "測量1" "測量2" ...
$ V2: chr "1" "AAA" "10" "100" ...
$ V3: chr "2" "AAA" "20" "200" ...
$ V4: chr "3" "BBB" "30" "300" ...
$ V5: chr "4" "BBB" "40" "400" ...
$ V6: chr "5" "CCC" "50" "500" ...
>
# 資料轉換(t函數),結果是矩陣 matrix,此結果與data.frame之需求不符合
> t(myData)
[,1] [,2] [,3] [,4] [,5] [,6]
V1 "編號" "型式" "測量1" "測量2" "測量3" "結果"
V2 "1" "AAA" "10" "100" "1000" "OK"
V3 "2" "AAA" "20" "200" "2000" "OK"
V4 "3" "BBB" "30" "300" "3000" "ERROR"
V5 "4" "BBB" "40" "400" "4000" "ERROR"
V6 "5" "CCC" "50" "500" "5000" "OK"
> class(t(myData))
[1] "matrix"
>
# 將資料轉換之矩陣再轉為資料框 data.frame,此結果應該是可以使用
> myData.df <- as.data.frame(t(myData), stringsAsFactors=FALSE)
> str(myData.df)
'data.frame': 6 obs. of 6 variables:
$ V1: chr "編號" "1" "2" "3" ...
$ V2: chr "型式" "AAA" "AAA" "BBB" ...
$ V3: chr "測量1" "10" "20" "30" ...
$ V4: chr "測量2" "100" "200" "300" ...
$ V5: chr "測量3" "1000" "2000" "3000" ...
$ V6: chr "結果" "OK" "OK" "ERROR" ...
> myData.df
V1 V2 V3 V4 V5 V6
V1 編號 型式 測量1 測量2 測量3 結果
V2 1 AAA 10 100 1000 OK
V3 2 AAA 20 200 2000 OK
V4 3 BBB 30 300 3000 ERROR
V5 4 BBB 40 400 4000 ERROR
V6 5 CCC 50 500 5000 OK
>
# 欄位名稱調整
> names(myData.df) <- myData.df[1,]
>
# 考慮刪除列名稱
> row.names(myData.df) <- NULL
>
# 刪除第1列多餘資料
> (myData.df <- myData.df[-1,])
編號 型式 測量1 測量2 測量3 結果
V2 1 AAA 10 100 1000 OK
V3 2 AAA 20 200 2000 OK
V4 3 BBB 30 300 3000 ERROR
V5 4 BBB 40 400 4000 ERROR
V6 5 CCC 50 500 5000 OK
> str(myData.df)
'data.frame': 5 obs. of 6 variables:
$ 編號 : chr "1" "2" "3" "4" ...
$ 型式 : chr "AAA" "AAA" "BBB" "BBB" ...
$ 測量1: chr "10" "20" "30" "40" ...
$ 測量2: chr "100" "200" "300" "400" ...
$ 測量3: chr "1000" "2000" "3000" "4000" ...
$ 結果 : chr "OK" "OK" "ERROR" "ERROR" ...
>
# 目前資料轉換正常,唯數值字料尚須轉換
# 選取1欄,將字串轉換為數值資料
> myData.df$測量1
[1] "10" "20" "30" "40" "50"
> as.numeric(myData.df$測量1)
[1] 10 20 30 40 50
>
> # 如果資料欄位較多,似乎須考量非一行一行轉換!
> # 判斷將所有欄資料並轉換為數值資料,保留無法轉換為數值之字串資料
> for (i in 1:dim(myData.df)[2]) {
+ if (all(!is.na(as.numeric(myData.df[,i])))) {
+ myData.df[,i] <- as.numeric(myData.df[,i])
+ }
+ }
Warning messages:
1: NAs introduced by coercion
2: NAs introduced by coercion
>
> # 第1,3-5欄已轉換為數值資料
> str(myData.df)
'data.frame': 5 obs. of 6 variables:
$ 編號 : num 1 2 3 4 5
$ 型式 : chr "AAA" "AAA" "BBB" "BBB" ...
$ 測量1: num 10 20 30 40 50
$ 測量2: num 100 200 300 400 500
$ 測量3: num 1000 2000 3000 4000 5000
$ 結果 : chr "OK" "OK" "ERROR" "ERROR" ...
> myData.df
編號 型式 測量1 測量2 測量3 結果
V2 1 AAA 10 100 1000 OK
V3 2 AAA 20 200 2000 OK
V4 3 BBB 30 300 3000 ERROR
V5 4 BBB 40 400 4000 ERROR
V6 5 CCC 50 500 5000 OK
> # end
R code:
##################################### title : 列轉換為行之數值資料
# date : 2015.9.3
# author : Ming-Chang Lee
# email : alan9956@gmail.com
# RWEPA : http://rwepa.blogspot.tw/
# encoding : UTF-8
####################################
# 匯入資料
myData <- read.table("rowdata.csv", sep=",", stringsAsFactors=FALSE)
myData
str(myData)
# 資料轉換(t函數),結果是矩陣 matrix
t(myData)
class(t(myData))
# 將資料轉換之矩陣再轉為資料框 data frame
myData.df <- as.data.frame(t(myData), stringsAsFactors=FALSE)
str(myData.df)
myData.df
# 欄位名稱調整
names(myData.df) <- myData.df[1,]
# 考慮刪除列名稱
row.names(myData.df) <- NULL
# 刪除第1列多餘資料
(myData.df <- myData.df[-1,])
str(myData.df)
# 目前資料轉換正常,唯數值字料尚須轉換
# 選取1欄,將字串轉換為數值資料
myData.df$測量1
as.numeric(myData.df$測量1)
# 如果資料欄位較多,似乎須考量非一行一行轉換!
# 判斷將所有欄資料並轉換為數值資料,保留無法轉換為數值之字串資料
for (i in 1:dim(myData.df)[2]) {
if (all(!is.na(as.numeric(myData.df[,i])))) {
myData.df[,i] <- as.numeric(myData.df[,i])
}
}
# 第1,3-5欄已轉換為數值資料
str(myData.df)
myData.df
# end
注意: if (all(!is.na(as.numeric(myData.df[,i])))) { ... }, 其中 if ( ) 如果不加上括號,結果會有錯誤 ^_^
回覆刪除版大您好:
回覆刪除這裡有的題外問題想詢問,關於R的自動化,以這題為例是否有方法讓rscript轉為exe檔。每次一點擊就自行跑完程式嗎?
謝謝閱讀
Hi Chih-Wei,
回覆刪除(1).
考慮 Windows 環境中R的安裝目錄為 C:\R\R-3.2.2, 資料夾目錄為 C:\rdata.
C:\rdata\my_script.bat 輸入以下內容:
C:\R\R-3.2.2\bin\R.exe CMD BATCH --vanilla --slave "c:\rdata\my_script.R"
(2).
C:\rdata\my_script.R 輸入以下內容:
# batch test
setwd("C:/rdata")
ind <- sample(nrow(iris), 10)
mydata <- iris[ind,]
filename <- paste0("mydata", "_", format(Sys.time(), "%Y.%m.%d_%H.%M.%S"), ".csv")
write.csv(mydata, file=filename, row.names=FALSE)
# end
(3).
執行以下程式即可完成本測試R程式:
C:\rdata\my_script.bat
(4).
參考結果已新增 "mydata_2015.11.02_00.01.59.csv"
http://web.ydu.edu.tw/~alan9956/rdata/r_batch.png
http://web.ydu.edu.tw/~alan9956/rdata/r_batch_output.png
執行完成會有 my_script.Rout 檔案, 其內容 elapsed 對應封行時間為 0.26秒, 結果如下:
回覆刪除C:\WINDOWS\system32>TYPE C:\rdata\my_script.Rout
> proc.time()
user system elapsed
0.29 0.01 0.26