2012-02-18 33 views
5

Các chức năng làm tan chảy/đóng gói trong gói định hình lại rất tuyệt, nhưng tôi không chắc liệu có cách đơn giản để áp dụng chúng khi các biến đo được có các loại khác nhau hay không. Ví dụ, đây là một đoạn trích từ dữ liệu trong đó mỗi MD cung cấp các giới và trọng lượng của ba bệnh nhân:Các lựa chọn thay thế cho số liệu thống kê :: reshape

ID PT1 WT1 PT2 WT2 PT3 WT3 
1 "M" 170 "M" 175 "F" 145 
... 

nơi mục tiêu là để định hình lại nên mỗi hàng là một bệnh nhân:

ID PTNUM GENDER WEIGHT 
1 1  "M" 170 
1 2  "M" 175 
1 3  "F" 145 
... 

Sử dụng chức năng định hình lại trong gói thống kê là một tùy chọn mà tôi biết, nhưng tôi đăng bài ở đây với hy vọng rằng người dùng R nhiều kinh nghiệm hơn tôi sẽ đăng khác, hy vọng các phương pháp tốt hơn. Cảm ơn nhiều!

-

@Vincent Zoonekynd:

tôi thích ví dụ của bạn rất nhiều, vì vậy tôi khái quát hóa nó để biến phức.

# Sample data 
n <- 5 
d <- data.frame(
    id = 1:n, 
    p1 = sample(c("M","F"),n,replace=TRUE), 
    q1 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w1 = round(runif(n,100,200)), 
    y1 = round(runif(n,100,200)), 
    p2 = sample(c("M","F"),n,replace=TRUE), 
    q2 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w2 = round(runif(n,100,200)), 
    y2 = round(runif(n,100,200)), 
    p3 = sample(c("M","F"),n,replace=TRUE), 
    q3 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w3 = round(runif(n,100,200)), 
    y3 = round(runif(n,100,200)) 
) 
# Reshape the data.frame, one variable at a time 
library(reshape) 
d1 <- melt(d, id.vars="id", measure.vars=c("p1","p2","p3","q1","q2","q3")) 
d2 <- melt(d, id.vars="id", measure.vars=c("w1","w2","w3","y1","y2","y3")) 
d1 = cbind(d1,colsplit(d1$variable,names=c("var","ptnum"))) 
d2 = cbind(d2,colsplit(d2$variable,names=c("var","ptnum"))) 
d1$variable = NULL 
d2$variable = NULL 
d1c = cast(d1,...~var) 
d2c = cast(d2,...~var) 
# Join the two data.frames 
d3 = merge(d1c, d2c, by=c("id","ptnum"), all=TRUE) 

-

suy nghĩ cuối cùng: động lực của tôi cho câu hỏi này là để tìm hiểu về thay thế cho gói Reshape khác hơn so với số liệu thống kê :: reshape chức năng. Hiện tại, tôi đã đạt được các kết luận sau:

  • Gắn vào số liệu thống kê :: định hình lại khi bạn có thể. Miễn là bạn nhớ sử dụng danh sách thay vì một vectơ đơn giản cho đối số "thay đổi", bạn sẽ không gặp rắc rối gì. Đối với các tập dữ liệu nhỏ hơn - một vài nghìn trường hợp bệnh nhân có tổng số ít hơn 200 biến là những gì tôi đã xử lý với thời gian này - tốc độ thấp hơn của hàm này đáng để đơn giản hóa mã.

  • Để sử dụng phương pháp đúc/làm nóng trong gói định hình lại của Hadley Wickham (hoặc reshape2), bạn phải chia các biến thành hai bộ, một biến bao gồm các biến số và một biến khác. Khi tập dữ liệu của bạn đủ lớn mà bạn tìm thấy số liệu thống kê :: định hình lại không thể chịu nổi, tôi tưởng tượng bước bổ sung của việc chia các biến của bạn thành hai bộ sẽ không có vẻ quá tệ.

+3

Tốt hơn theo nghĩa nào? định hình lại có nghĩa là cho các công việc như thế này, vậy tại sao không sử dụng nó? – Fojtasek

+0

Tính năng định hình lại hoạt động tốt miễn là người dùng nhớ lại sử dụng dạng chuẩn của đối số thay đổi (danh sách): [link] (http://www.mail-archive.com/[email protected]/msg160715 .html) Với R, tôi liên tục ngạc nhiên bởi sự tồn tại của các lựa chọn thay thế mà tôi không biết, vì vậy tôi nghĩ ai đó sẽ đăng các cách tiếp cận khác. Một ví dụ về việc xác định "tốt hơn" sẽ là tốc độ: trong trải nghiệm chủ quan được thừa nhận của tôi, cast/melt dường như nhanh hơn so với định dạng lại được tích hợp sẵn. –

+0

Tôi không nhận thấy điều này, cảm ơn. Bây giờ tôi đã thay đổi thư viện từ reshape2 để định hình lại.Bạn vẫn có thể sử dụng reshape2 nếu muốn: bạn sẽ phải thêm đối số mẫu với giá trị "" vào cuộc gọi colsplit(). –

Trả lời

3

Bạn có thể xử lý mỗi biến riêng rẽ, và tham gia vào kết quả hai data.frames.

# Sample data 
n <- 5 
d <- data.frame(
    id = 1:n, 
    pt1 = sample(c("M","F"),n,replace=TRUE), 
    wt1 = round(runif(n,100,200)), 
    pt2 = sample(c("M","F"),n,replace=TRUE), 
    wt2 = round(runif(n,100,200)), 
    pt3 = sample(c("M","F"),n,replace=TRUE), 
    wt3 = round(runif(n,100,200)) 
) 
# Reshape the data.frame, one variable at a time 
library(reshape2) 
d1 <- melt(d, 
    id.vars="id", measure.vars=c("pt1","pt2","pt3"), 
    variable.name="patient", value.name="gender" 
) 
d2 <- melt(d, 
    id.vars="id", measure.vars=c("wt1","wt2","wt3"), 
    variable.name="patient", value.name="weight" 
) 
d1$patient <- as.numeric(gsub("pt", "", d1$patient)) 
d2$patient <- as.numeric(gsub("wt", "", d1$patient)) 
# Join the two data.frames 
merge(d1, d2, by=c("id","patient"), all=TRUE) 
+0

Cảm ơn bạn, điều này có ý nghĩa. Mã này dài hơn yêu cầu cho số liệu thống kê :: định hình lại, nhưng có lẽ đáng để đạt được hiệu quả khi có nhiều biến, thường là trường hợp của tôi. –

2

Tôi nghĩ chức năng reshape trong gói thống kê là đơn giản nhất. Đây là một ví dụ đơn giản, điều này có làm những gì bạn muốn không?

> tmp 
    id val val2 cat 
1 1 1 14 a 
2 1 2 13 b 
3 2 3 12 b 
4 2 4 11 a 
> tmp2 <- tmp 
> tmp2$t <- ave(tmp2$val, tmp2$id, FUN=seq_along) 
> tmp2 
    id val val2 cat t 
1 1 1 14 a 1 
2 1 2 13 b 2 
3 2 3 12 b 1 
4 2 4 11 a 2 
> reshape(tmp2, idvar='id', timevar='t', direction='wide') 
    id val.1 val2.1 cat.1 val.2 val2.2 cat.2 
1 1  1  14  a  2  13  b 
3 2  3  12  b  4  11  a 

Hy vọng rằng bệnh nhân quan hệ tình dục của bạn không được thay đổi mỗi cuộc hẹn, nhưng có thể có các biến phân loại khác mà thay đổi giữa các lần

+0

Những gì tôi đã có trong tâm trí là nhiều bệnh nhân mỗi MD, không phải là cùng một bệnh nhân đo trên nhiều lần. Nhưng tôi đồng ý rằng mã với số liệu thống kê :: định hình lại chắc chắn là nhỏ gọn hơn, miễn là người ta nhận thức được các gotchas tiềm năng: [xem liên kết] (http://www.mail-archive.com/[email protected] .org/msg160715.html) –

+0

Vì vậy, trong ví dụ sử dụng id của tôi làm id của bác sĩ và nhiều giá trị đại diện cho bệnh nhân. –