2013-04-04 59 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