2012-08-16 47 views
3

對於看似簡單的問題抱歉,但似乎無法找到解決以下重新排列問題的解決方案。我已經習慣使用read.csv來讀取帶有標題行的文件,但是我有一個帶有兩個「標題」行的Excel電子表格 - 單元格標識符(a,b,c ... g)以及三組(測量值(X,Y和z;每個1000)對每個小區:將兩個標題的csv讀入data.frame

a   b  
x y z x y z 
10 1 5 22 1 6 
12 2 6 21 3 5 
12 2 7 11 3 7 
13 1 4 33 2 8 
12 2 5 44 1 9 

CSV文件如下:

a,,,b,, 
x,y,z,x,y,z 
10,1,5,22,1,6 
12,2,6,21,3,5 
12,2,7,11,3,7 
13,1,4,33,2,8 
12,2,5,44,1,9 

我怎樣才能在R A data.frame如下所示?

cell x y z 
a 10 1 5 
a 12 2 6 
a 12 2 7 
a 13 1 4 
a 12 2 5 
b 22 1 6 
b 21 3 5 
b 11 3 7 
b 33 2 8 
b 44 1 9 
+3

你會發現,如果你花時間讓你的問題可以重現,你會得到更好的答案。請遵循指南(http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example),特別注意關於'dput()'的部分。謝謝! – 2012-08-16 12:28:47

+1

@ AriB.Friedman,'dput()'很好,我一般都很感激,但是如何使用'dput()'來解決'read.csv()'問題呢?在Dropbox上託管CSV可能是另一種選擇,但會出現持久性問題。我認爲*這個問題 - 即使沒有OP的編輯 - 是合理的,儘管對我們其他人來說更多的工作。 – A5C1D2H2I1M1N2O1R2T1 2012-08-16 16:04:14

+0

@mrdwab我在想他可以'輸出(read.csv())',因爲這不一定是一個read.csv問題,而是一個重新整形後的讀入。 – 2012-08-16 17:54:03

回答

6

使用基礎R reshape()

temp = read.delim(text="a,,,b,, 
x,y,z,x,y,z 
10,1,5,22,1,6 
12,2,6,21,3,5 
12,2,7,11,3,7 
13,1,4,33,2,8 
12,2,5,44,1,9", header=TRUE, skip=1, sep=",") 
names(temp)[1:3] = paste0(names(temp[1:3]), ".0") 
OUT = reshape(temp, direction="long", ids=rownames(temp), varying=1:ncol(temp)) 
OUT 
#  time x y z id 
# 1.0 0 10 1 5 1 
# 2.0 0 12 2 6 2 
# 3.0 0 12 2 7 3 
# 4.0 0 13 1 4 4 
# 5.0 0 12 2 5 5 
# 1.1 1 22 1 6 1 
# 2.1 1 21 3 5 2 
# 3.1 1 11 3 7 3 
# 4.1 1 33 2 8 4 
# 5.1 1 44 1 9 5 

基本上,你應該只跳過第一行,那裏有字母A-G每個第三列。由於子列名全部相同,因此R將在第三列之後的所有列之後自動附加分組編號;所以我們需要爲前三列添加一個分組編號。

然後你可以創建一個「id」變量,或者,正如我在這裏所做的那樣,只需使用這些ID的行名即可。

您可以更改 「時間」 變量設置爲 「細胞」 變量,如下所示:

# Change the following to the number of levels you actually have 
OUT$cell = factor(OUT$time, labels=letters[1:2]) 

然後,刪除 「時間」 欄:

OUT$time = NULL 

更新

要在下面的評論中回答一個問題,如果第一個標籤不是字母,這應該仍然沒有問題。我會採取的序列如下:

temp = read.csv("path/to/file.csv", skip=1, stringsAsFactors = FALSE) 
GROUPS = read.csv("path/to/file.csv", header=FALSE, 
        nrows=1, stringsAsFactors = FALSE) 
GROUPS = GROUPS[!is.na(GROUPS)] 
names(temp)[1:3] = paste0(names(temp[1:3]), ".0") 
OUT = reshape(temp, direction="long", ids=rownames(temp), varying=1:ncol(temp)) 
OUT$cell = factor(temp$time, labels=GROUPS) 
OUT$time = NULL 
+0

如果OP有另一個第一個標籤而不是一個瑣碎的字母怎麼辦?是否有可能只讀第一行? – 2012-08-16 13:41:16

+0

@lselzer,我已添加更新。我不認爲這很困難 - 你只需要創建一個只讀入第一行並將其用於「單元格」標籤的對象。 – A5C1D2H2I1M1N2O1R2T1 2012-08-16 15:58:28

+0

@mrdwab謝謝你的回答。它爲我工作得很好。我很高興這不是一件微不足道的事情。 – user441706 2012-08-17 08:24:22