簡體   English   中英

在R中的相同數據框中綁定具有相似列名的列

[英]Binding columns with similar column names in the same dataframe in 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

有多個列具有相同的名稱。 我想重新排列數據框,以便具有相同名稱的列組合成它們自己的超級列,這樣只剩下唯一的列名,例如:

> 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

有關如何做到這一點的任何想法? 提前致謝!

我猜想,這將成功。

說明

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

unlist將上面的列轉換為1個單向量

unname將刪除一些給這些向量的迷路unname

unique(names(df))將在df為您提供唯一的列名

sapply會將內聯函數應用於所有unique(names(df))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

我的版本:

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

然后我使用split每個唯一級別variablevalue列:

$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可以成為你需要的數據結構。

使用%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

我將按列名稱對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

我現在不在電腦前,所以不能測試這個,但是...... 這可能有效:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM