2013-04-04 63 views
6

在同一個數據幀相似的列名綁定列我有一個數據幀看起來有點像這樣:與R中

df <- data.frame(0:2, 1:3, 2:4, 5:7, 6:8, 2:4, 0:2, 1:3, 2:4) 
colnames(df) <- rep(c('a', 'b', 'c'), 3) 
> df 
    a b c a b c a b c 
1 0 1 2 5 6 2 0 1 2 
2 1 2 3 6 7 3 1 2 3 
3 2 3 4 7 8 4 2 3 4 

有具有相同名稱的多個列。我想重新排列的數據幀,使具有相同名稱的列合併到自己的supercolumn,以便有隻留下唯一的列名,例如:

> df 
    a b c 
1 0 1 2 
2 1 2 3 
3 2 3 4 
4 5 6 2 
5 6 7 3 
6 7 8 4 
7 0 1 2 
8 1 2 3 
9 2 3 4 

如何做到這一點有什麼想法?提前致謝!

+0

歡迎堆棧溢出!也請說明你到現在爲止嘗試過什麼。 SO不是讓你的代碼免費編寫的地方。也告訴你到現在爲止你還嘗試了什麼,這也表明你真的想從解決方案中學習,並且不僅僅是解決方案 – 2013-04-04 05:23:56

+3

... @ geektrader,但他提供了一個可重複的例子,讓他得到我的讚賞。另外,這個問題非常有限,並且有一個明確的答案,只需幾分鐘就可以得到大量答案的證實。人們要求我們去做他們的工作的例子要多得多。 – 2013-04-04 05:35:19

+0

@geektrader - 感謝您的歡迎!對於未來,我一定會銘記您的建議。我向你保證,我在發佈之前嘗試了很多東西。 – tkvn 2013-04-04 05:57:35

回答

7

這將做的伎倆,我想。

說明

df[,names(df) == 'a']將選擇具有名稱a

unlist所有列將上述列轉換成1個單個載體

unname將刪除給予這些載體一些雜散rownames。

unique(names(df))會給你唯一的列名在df

sapply將適用於內聯函數和unique(names(df))

> df 
    a b c a b c a b c 
1 0 1 2 5 6 2 0 1 2 
2 1 2 3 6 7 3 1 2 3 
3 2 3 4 7 8 4 2 3 4 
> sapply(unique(names(df)), function(x) unname(unlist(df[,names(df)==x]))) 
     a b c 
[1,] 0 1 2 
[2,] 1 2 3 
[3,] 2 3 4 
[4,] 5 6 2 
[5,] 6 7 3 
[6,] 7 8 4 
[7,] 0 1 2 
[8,] 1 2 3 
[9,] 2 3 4 
+0

這與我想出的幾乎完全相同,除了使用'unname'清理 - 因此:+1。 – thelatemail 2013-04-04 05:43:37

0

我現在不在電腦,所以不能測試這個,但.. .. ..。 這可能工作:

do.call(cbind, 
    lapply(names(df) function(x) do.call(rbind, df[, names(df) == x]))) 
2

所有值使用%in%一些unlisting

zz <- lapply(unique(names(df)), function(x,y) as.vector(unlist(df[which(y %in% x)])),y=names(df)) 
names(zz) <- unique(names(df)) 
as.data.frame(zz) 
    a b c 
1 0 1 2 
2 1 2 3 
3 2 3 4 
4 5 6 2 
5 6 7 3 
6 7 8 4 
7 0 1 2 
8 1 2 3 
9 2 3 4 
5

我的版本:

library(reshape) 
as.data.frame(with(melt(df), split(value, variable))) 
    a b c 
1 0 1 2 
2 1 2 3 
3 2 3 4 
4 0 1 2 
5 1 2 3 
6 2 3 4 
7 0 1 2 
8 1 2 3 
9 2 3 4 

在步驟使用melt我變換數據集:

$a 
[1] 0 1 2 0 1 2 0 1 2 

$b 
[1] 1 2 3 1 2 3 1 2 3 

$c 
[1] 2 3 4 2 3 4 2 3 4 

則這僅需要一個:

> melt(df) 
Using as id variables 
    variable value 
1   a  0 
2   a  1 
3   a  2 
4   b  1 
5   b  2 
6   b  3 
7   c  2 
8   c  3 
9   c  4 
10  a  0 
11  a  1 
12  a  2 
13  b  1 
14  b  2 
15  b  3 
16  c  2 
17  c  3 
18  c  4 
19  a  0 
20  a  1 
21  a  2 
22  b  1 
23  b  2 
24  b  3 
25  c  2 
26  c  3 
27  c  4 

然後我使用split分裂爲variable每個唯一水平valueas.data.frame成爲您需要的數據結構。

2

我會排序data.frame通過列名,不公開,並在matrix使用as.data.frame

A <- unique(names(df))[order(unique(names(df)))] 
B <- matrix(unlist(df[, order(names(df))], use.names=FALSE), ncol = length(A)) 
B <- setNames(as.data.frame(B), A) 
B 
# a b c 
# 1 0 1 2 
# 2 1 2 3 
# 3 2 3 4 
# 4 5 6 2 
# 5 6 7 3 
# 6 7 8 4 
# 7 0 1 2 
# 8 1 2 3 
# 9 2 3 4 
+0

+1,雖然代碼看起來相當艱鉅,但也許少得多,然後一些其他答案... – 2013-04-04 05:37:46