2013-04-04 35 views
6

Tôi có một khung dữ liệu trông hơi như thế này:cột Binding với tên cột tương tự trong dataframe cùng trong 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 

Có nhiều cột có cùng tên. Tôi muốn sắp xếp lại các khung dữ liệu để các cột với cùng tên kết hợp vào supercolumn riêng của họ, do đó chỉ có tên cột độc đáo trái, ví dụ:

> 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 

Bất kỳ suy nghĩ về cách để làm điều này? Cảm ơn trước!

+0

Chào mừng bạn đến Stack Overflow! Xin vui lòng cũng cho thấy những gì bạn đã thử cho đến bây giờ. SO không phải là nơi để viết mã của bạn miễn phí. Cũng nói với những gì bạn đã cố gắng cho đến bây giờ cũng cho thấy rằng bạn đang thực sự tìm kiếm để tìm hiểu từ các giải pháp và không chỉ sau khi giải pháp –

+3

... @ geektrader nhưng ông đã cung cấp một ví dụ tái sản xuất, có được anh ta upvote của tôi.Ngoài ra, câu hỏi được giới hạn độc đáo, với một câu trả lời rõ ràng, được xác nhận bởi số lượng lớn câu trả lời chỉ trong vài phút. Có nhiều ví dụ tồi tệ hơn nhiều về những người yêu cầu chúng tôi làm công việc của họ. –

+0

@geektrader - Cảm ơn sự chào đón! Tôi chắc chắn sẽ giữ lời khuyên của bạn trong tương lai. Và tôi đảm bảo với bạn rằng tôi đã thử rất nhiều thứ trước khi đăng. – tkvn

Trả lời

7

Điều này sẽ thực hiện thủ thuật, tôi cho là vậy.

Giải thích

df[,names(df) == 'a'] sẽ chọn tất cả các cột với tên a

unlist sẽ chuyển đổi trên cột vào 1 vector đơn

unname sẽ loại bỏ một số rownames đi lạc trao cho những vectơ.

unique(names(df)) sẽ cung cấp cho bạn tên cột duy nhất trong df

sapply sẽ áp dụng các chức năng nội tuyến cho tất cả các giá trị của 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

Điều này gần như giống với những gì tôi nghĩ ra, ngoại trừ việc dọn dẹp bằng cách sử dụng 'unname' - do đó: +1. – thelatemail

0

Hiện tôi không có máy tính, vì vậy không thể kiểm tra điều này, nhưng ... điều này có thể hoạt động:

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

Sử dụng %in% và một số 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

phiên bản của tôi:

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 

Trong bước sử dụng melt tôi chuyển đổi dữ liệu:

> 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 

Sau đó, tôi chia ra các cột value cho mỗi cấp độ độc đáo của variable sử dụng split:

$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 

thì đây chỉ cần một as.data.frame để trở thành cấu trúc dữ liệu bạn cần.

2

tôi sẽ sắp xếp các data.frame theo tên cột, không công khai, và sử dụng as.data.frame trên 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 
+0

+1, mặc dù mã trông khá khó khăn, nhưng có lẽ ít hơn nhiều nên một số câu trả lời khác ... –

Các vấn đề liên quan