2012-04-06 33 views
8

Tôi có một data.frame trông như thế này:Tái nhiều biến rộng với dàn diễn viên

> head(ff.df) 
    .id pio caremgmt prev price surveyNum 
1 1 2  2 1  2   1 
2 1 2  1 2  1   2 
3 1 1  1 2  2   3 
4 1 2  2 1  5   4 
5 1 1  1 1  3   5 
6 1 1  2 2  4   6 

tôi muốn định hình lại tất cả bốn biến phi-id rộng id. Nói cách khác, tôi muốn colnames:

surveyNum pio1 pio2 pio3 caremgmt1 caremgmt2 caremgmt3 prev1 prev2 prev3 price1 price2 price3 

tôi có thể làm điều đó cho một biến duy nhất:

> cast(ff.df, surveyNum~.id, value=c("pio")) 
    surveyNum 1 2 3 
1   1 2 2 2 
2   2 2 1 2 
3   3 1 2 1 
4   4 2 1 1 
5   5 1 2 2 
6   6 1 2 1 
7   7 1 1 2 
8   8 2 2 1 
9   9 1 1 2 
10  10 1 1 1 
11  11 2 2 1 
12  12 1 2 2 
13  13 1 1 1 
14  14 2 1 1 
15  15 1 2 1 
16  16 2 1 2 
17  17 1 2 2 
18  18 2 1 2 
19  19 1 2 2 
20  20 2 2 2 
21  21 2 1 1 
22  22 1 2 1 
23  23 2 1 1 
24  24 2 1 2 

Nhưng khi tôi thử nó cho một vài nó chỉ thất bại hoàn toàn:

> cast(ff.df, surveyNum~.id, value=c("pio","caremgmt","prev","price")) 
Error in data.frame(data[, c(variables), drop = FALSE], result = data$value) : 
    arguments imply differing number of rows: 72, 0 
In addition: Warning message: 
In names(data) == value : 
    longer object length is not a multiple of shorter object length 

Bất kỳ gợi ý nào? Tôi có thể sử dụng cơ sở (số liệu thống kê) reshape lệnh, nhưng tôi thực sự cố gắng để thoát khỏi nó như là nó gây ra quá nhiều nhãn hiệu da đầu chấn thương từ tóc kéo ....

ff.df <- structure(list(.id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), pio = structure(c(2L, 
2L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 
1L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 
1L, 2L, 2L, 1L, 2L, 1L, 1L), .Label = c("1", "2"), class = "factor"), 
    caremgmt = structure(c(2L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 
    2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 2L, 
    1L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
    1L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 
    1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 1L, 
    1L, 2L, 2L), .Label = c("1", "2"), class = "factor"), prev = structure(c(1L, 
    2L, 2L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
    1L, 2L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 
    2L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 
    2L, 2L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 
    1L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L), .Label = c("1", 
    "2"), class = "factor"), price = structure(c(2L, 1L, 2L, 
    5L, 3L, 4L, 1L, 5L, 4L, 3L, 1L, 2L, 6L, 6L, 5L, 4L, 6L, 3L, 
    5L, 6L, 3L, 1L, 2L, 4L, 3L, 5L, 2L, 5L, 4L, 5L, 6L, 6L, 4L, 
    6L, 4L, 1L, 2L, 3L, 1L, 2L, 2L, 5L, 1L, 6L, 1L, 3L, 4L, 3L, 
    6L, 5L, 5L, 4L, 4L, 2L, 2L, 2L, 6L, 3L, 1L, 4L, 4L, 5L, 1L, 
    3L, 6L, 1L, 3L, 5L, 1L, 3L, 6L, 2L), .Label = c("1", "2", 
    "3", "4", "5", "6"), class = "factor"), surveyNum = c(1L, 
    2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 
    15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 1L, 2L, 
    3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 
    16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 1L, 2L, 3L, 
    4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 
    17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L)), .Names = c(".id", 
"pio", "caremgmt", "prev", "price", "surveyNum"), row.names = c(NA, 
-72L), class = "data.frame") 
+0

câu hỏi liên quan: http://stackoverflow.com/questions/27247078/reshape-multiple-values-at- một lần-trong-r – landroni

Trả lời

13

Tôi nghĩ vấn đề là rằng ff.df chưa đủ nóng chảy. Hãy thử điều này:

library(reshape) 

# Melt it down 
ff.melt <- melt(ff.df, id.var = c("surveyNum", ".id")) 

# Note the new "variable" column, which will be combined 
# with .id to make each column header 
head(ff.melt) 

    surveyNum .id variable value 
1   1 1  pio  2 
2   2 1  pio  2 
3   3 1  pio  1 
4   4 1  pio  2 
5   5 1  pio  1 
6   6 1  pio  1 

# Cast it out - note that .id comes after variable in the formula; 
# I think the only effect of that is that you get "pio_1" instead of "1_pio" 
ff.cast <- cast(ff.melt, surveyNum ~ variable + .id) 

head(ff.cast) 

    surveyNum pio_1 pio_2 pio_3 caremgmt_1 caremgmt_2 caremgmt_3 prev_1 prev_2 prev_3 price_1 price_2 price_3 
1   1  2  2  2   2   1   1  1  2  2  2  6  3 
2   2  2  1  2   1   2   2  2  2  1  1  5  5 
3   3  1  2  1   1   2   1  2  1  2  2  5  2 
4   4  2  1  1   2   2   2  1  2  2  5  4  5 
5   5  1  2  2   1   2   1  1  1  1  3  4  4 
6   6  1  2  1   2   1   1  2  1  1  4  2  5 

Điều đó có giúp bạn không?

Về cơ bản, khi truyền, các biến được chỉ định ở phía bên tay phải của công thức đúc sẽ quyết định các cột sẽ xuất hiện trong kết quả truyền. Bằng cách chỉ cho biết .id, tôi tin rằng bạn đang yêu cầu cast bằng cách nào đó nhồi nhét tất cả các giá trị vectơ đó vào ba cột - 1, 2 và 3. Làm nóng dữ liệu tất cả các chiều xuống tạo cột variable, cho phép bạn chỉ định sự kết hợp của các vectơ .idvariable sẽ xác định các cột của khung dữ liệu truyền.

(Xin lỗi nếu tôi là lặp đi lặp lại/pedantic! Tôi đang cố gắng để làm việc nó ra cho bản thân mình, quá)

+2

PS: 'reshape2' đã được khoảng một thời gian bây giờ, và nó thực sự là nhanh hơn nhiều so với bản gốc. Kiểm tra [thông báo của Hadley] (https://stat.ethz.ch/pipermail/r-packages/2011/001204.html). Thay đổi duy nhất bạn cần thực hiện trong đoạn mã trên là thay đổi 'cast()' thành 'dcast()'. –

+0

Điều đó thực hiện điều đó. Cảm ơn! Một bước nữa trên con đường dẫn đến sự giác ngộ của tôi. –

+0

Re: bình luận của bạn. Tôi nghĩ rằng tôi muốn nó như '.id ~ variable' vì nó ảnh hưởng đến thứ tự của data.frame cuối cùng. –

7

Bạn có thể làm điều này với các chức năng trong reshapebase R. Trật tự cột là một chút kỳ lạ, nhưng có thể được sửa dễ dàng.

reshape(ff.df, direction = 'wide', idvar = "surveyNum", timevar = '.id') 
+0

Tôi đồng ý, và tôi chắc chắn quen thuộc hơn với 'reshape' hơn là' cast' (mặc dù tôi sử dụng 'melt' mọi lúc), nhưng tôi thực sự coi thường cú pháp' reshape' nên tôi tránh sử dụng nó. –

+0

Có. 'reshape' là rực rỡ nhưng với cú pháp không cần thiết phức tạp. Tôi có thể viết một wrapper xung quanh nó một ngày nào đó. – Ramnath

+0

Tôi bắt đầu sử dụng khá nhiều thay đổi cơ bản chỉ khoảng một tháng trước. Cú pháp là khủng khiếp nhưng nó cực kỳ mạnh mẽ. +1 –

4

Bạn có thể làm điều này bằng dcast từ phiên bản devel của data.table tức v1.9.5

library(data.table) 
    ff.cast <- dcast(setDT(ff.df), surveyNum~.id, 
     value.var=c('pio', 'caremgmt', 'prev', 'price')) 
    head(ff.cast,3) 
    # surveyNum 1_pio 2_pio 3_pio 1_caremgmt 2_caremgmt 3_caremgmt 1_prev 2_prev 
    #1:   1  2  2  2   2   1   1  1  2 
    #2:   2  2  1  2   1   2   2  2  2 
    #3:   3  1  2  1   1   2   1  2  1 
    # 3_prev 1_price 2_price 3_price 
    #1:  2  2  6  3 
    #2:  1  1  5  5 
    #3:  2  2  5  2 
Các vấn đề liên quan