2012-05-03 39 views
21

我正在尋找一個快速的方式來獲得來回以下格式列表之間:名爲List到/從Data.Frame

$`a` 
    [1] 1 2 3 
$`b` 
    [1] 4 5 6 

/從以下格式的data.frame :

name x 
1 a 1 
2 a 2 
3 a 3 
4 b 4 
5 b 5 
6 b 6 

(並不真正關心什麼列的名稱,在這種情況下)。

這裏是上面R-格式使用的數據幀:

df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6)) 

同樣,我正在尋找兩個單獨的操作:一個將上述data.frame轉換爲列表,另一個將其轉換回data.frame。

回答

26

使用stackunstack在基R:

x <- data.frame(a=1:3, b=4:6) 

x 
    a b 
1 1 4 
2 2 5 
3 3 6 

使用stack從寬到高,即堆疊在彼此的頂部上的載體。

y <- stack(x) 
y 
    values ind 
1  1 a 
2  2 a 
3  3 a 
4  4 b 
5  5 b 
6  6 b 

使用unstack來做相反的操作。

unstack(y) 
    a b 
1 1 4 
2 2 5 
3 3 6 

如果你的數據結構更復雜一些比你所描述的,stackunstack可能不再是合適的。在這種情況下,您必須在基數R中使用reshape,或者在包裝號reshape2中使用meltdcast

7

也許是這樣的:

X <- split(df$x, df$name) 
data.frame(name = rep(names(X), sapply(X, length)), 
    x=do.call('c', X)) 

編輯:我決定Andrie和我的解決方案組合成似乎正是OP要求相當簡單。這就是說,我不太瞭解這樣一種情況,我會以這種方式處理數據,而不是像Andrie那樣處理數據,因爲無論如何,數據幀都是等長向量的列表。

# Your data set 
df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6)) 

# converting it to list of vectors 
X <- split(df[, 2], df[, 1]) 
# converting it to a dataframe 
Y <- stack(X)[, 2:1]; names(Y) <- names(df) 

# Take Y and feed it back to these lines to show it 
# switches back and forth 
(X <- split(Y[, 2], Y[, 1])) 
Y <- stack(X)[, 2:1]; names(Y) <- names(df);Y 
+0

+1我在想也許'熔化(as.data.frame(...),value.name ='x',variable.name ='name')'回到數據框。 – joran

+0

需要注意的是,拆分會重新排序數據幀,因爲它會構建第二個向量的因子。另請參見[爲兩個向量(名稱,值)創建一個命名列表](http://stackoverflow.com/questions/17842705/creating-a-named-list-from-two-vectors-names-values)解決方案使用'mapply'。 – jnas

2

我願提出希望不平凡的一句話是@Tyler林克的建議

X <- split(df$x, df$name) 

可以用

X <- split(df, df$name) 

@Tyler林克的分裂()的解釋更一般都做匹配將R食譜

http://my.safaribooksonline.com/book/programming/r/9780596809287/6dot1dot-splitting-a-vector-into-groups/id3392005

specifyin g可以將矢量分組,而實際上整個數據框可以分組。我認爲將數據框分組,而不是矢量分組將是更有價值的工具(實際上是我帶到這個崗位的原因)。

(df <- data.frame(name=c(rep("a",3),rep("b",3), rep("c",3)), x=c(1:3,4:6, 7:9))) 
(X <- split(df, df$name)) 

HTH。