7

我有一个看起来像这样的数据框:

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

有多个具有相同名称的列。我想重新排列数据框,使具有相同名称的列组合成它们自己的超列,这样就只剩下唯一的列名了,例如:

> 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

关于如何做到这一点的任何想法?提前致谢!

4

5 回答 5

9

我想这会成功的。

解释

df[,names(df) == 'a']将选择所有具有名称的列a

unlist将以上列转换为 1 个单个向量

unname将删除赋予这些向量的一些杂散行名。

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
于 2013-04-04T05:25:17.393 回答
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我转换数据集的步骤中:

> 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

然后我为每个独特的使用级别拆分value列:variablesplit

$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

那么这只需要一个as.data.frame成为你需要的数据结构。

于 2013-04-04T05:33:41.903 回答
2

使用%in%和一些不上市

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
于 2013-04-04T05:26:18.040 回答
2

我会data.frame按列名、取消列表排序,然后as.data.frame在 a 上使用matrix

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
于 2013-04-04T05:34:14.223 回答
0

我现在不在电脑前,所以无法测试这个,但是...... 这可能有效:

do.call(cbind, 
     lapply(names(df) function(x) do.call(rbind, df[, names(df) == x])) )
于 2013-04-04T05:25:03.577 回答