2012-03-13 15 views
14

Tôi biết từ lâu đến nay đã được hỏi quá nhiều lần ở đây nhưng tôi không thể tìm ra cách biến những điều sau thành định dạng dài. Bắn tôi thậm chí còn hỏi một trong những rộng đến dài với 2 biện pháp lặp đi lặp lại trên SO. Tôi trở nên thất vọng vì không có khả năng chuyển đổi dữ liệu của mình. Làm thế nào tôi có thể tắt chức năng này (nhằm biến không quan trọng):rộng đến dài nhiều biện pháp mỗi lần

 id trt work.T1 play.T1 talk.T1 total.T1 work.T2 play.T2 talk.T2 total.T2 
1 x1.1 cnt 0.34434350 0.7841665 0.1079332 0.88803151 0.64836951 0.87954320 0.7233519 0.5630988 
2 x1.2 tr 0.06132255 0.8426960 0.3338658 0.04685878 0.23478670 0.19711687 0.5164015 0.7617968 
3 x1.3 tr 0.36897981 0.1834721 0.3241316 0.76904051 0.07629721 0.06945971 0.4118995 0.7452974 
4 x1.4 tr 0.40759356 0.5285396 0.5654258 0.23022542 0.92309504 0.15733957 0.4132653 0.7078273 
5 x1.5 cnt 0.91433676 0.7029476 0.2031782 0.31518412 0.14721669 0.33345678 0.7620444 0.9868082 
6 x1.6 tr 0.88870525 0.9132728 0.2197045 0.28266959 0.82239037 0.18006177 0.2591765 0.4516309 
7 x1.7 cnt 0.98373218 0.2591739 0.6331153 0.71319565 0.41351839 0.14648269 0.7631898 0.1182174 
8 x1.8 tr 0.47719528 0.7926248 0.3525205 0.86213792 0.61252061 0.29057544 0.9824048 0.2386353 
9 x1.9 tr 0.69350823 0.6144696 0.8568732 0.10632352 0.06812050 0.93606889 0.6701190 0.4705228 
10 x1.10 cnt 0.42574646 0.7006205 0.9507216 0.55032776 0.90413220 0.10246047 0.5899279 0.3523231 

vào đây:

 id trt time  work  play  talk  total 
1 x1.1 cnt 1 0.34434350 0.78416653 0.1079332 0.88803151 
2 x1.2 tr 1 0.06132255 0.84269599 0.3338658 0.04685878 
3 x1.3 tr 1 0.36897981 0.18347215 0.3241316 0.76904051 
4 x1.4 tr 1 0.40759356 0.52853960 0.5654258 0.23022542 
5 x1.5 cnt 1 0.91433676 0.70294755 0.2031782 0.31518412 
6 x1.6 tr 1 0.88870525 0.91327276 0.2197045 0.28266959 
7 x1.7 cnt 1 0.98373218 0.25917392 0.6331153 0.71319565 
8 x1.8 tr 1 0.47719528 0.79262477 0.3525205 0.86213792 
9 x1.9 tr 1 0.69350823 0.61446955 0.8568732 0.10632352 
10 x1.10 cnt 1 0.42574646 0.70062053 0.9507216 0.55032776 
11 x1.1 cnt 2 0.64836951 0.87954320 0.7233519 0.56309884 
12 x1.2 tr 2 0.23478670 0.19711687 0.5164015 0.76179680 
13 x1.3 tr 2 0.07629722 0.06945971 0.4118995 0.74529740 
14 x1.4 tr 2 0.92309504 0.15733957 0.4132653 0.70782726 
15 x1.5 cnt 2 0.14721669 0.33345678 0.7620444 0.98680824 
16 x1.6 tr 2 0.82239038 0.18006177 0.2591765 0.45163091 
17 x1.7 cnt 2 0.41351839 0.14648269 0.7631898 0.11821741 
18 x1.8 tr 2 0.61252061 0.29057544 0.9824048 0.23863532 
19 x1.9 tr 2 0.06812050 0.93606889 0.6701190 0.47052276 
20 x1.10 cnt 2 0.90413220 0.10246047 0.5899279 0.35232307 

Tập dữ liệu

id <- paste('x', "1.", 1:10, sep="") 
set.seed(10) 
DF <- data.frame(id, trt=sample(c('cnt', 'tr'), 10, T), work.T1=runif(10), 
    play.T1=runif(10), talk.T1=runif(10), total.T1=runif(10), 
    work.T2=runif(10), play.T2=runif(10), talk.T2=runif(10), 
    total.T2=runif(10)) 

Cảm ơn bạn trước!

EDIT: Đã xảy ra sự cố khi tôi đang sử dụng set.seed (chắc chắn là lỗi tôi đã làm). Dữ liệu thực sự ở trên không phải là dữ liệu bạn sẽ nhận được nếu bạn sử dụng set.seed(10). Tôi để lại lỗi cho độ chính xác lịch sử và nó thực sự không ảnh hưởng đến các giải pháp mà mọi người đưa ra.

+0

Câu hỏi rõ ràng, ví dụ có thể tái sản xuất. +1 –

Trả lời

8

này là khá chặt chẽ và thay đổi tên của các cột nên trong tuyệt chiêu của bạn:

reshape(DF, 
     varying=c(work= c(3, 7), play= c(4,8), talk= c(5,9), total= c(6,10)), 
     direction="long") 

EDIT: Thêm một phiên bản gần như là một giải pháp chính xác:

reshape(DF, varying=list(work= c(3, 7), play= c(4,8), talk= c(5,9), total= c(6,10)), 
     v.names=c("Work", "Play", "Talk", "Total"), 
      # that was needed after changed 'varying' arg to a list to allow 'times' 
     direction="long", 
     times=1:2,  # substitutes number for T1 and T2 
     timevar="times") # to name the time col 
+1

cảm ơn bạn rất nhiều! Tôi đã gần đó nhưng không hoàn toàn hiểu những gì tôi đang làm. Rất dễ dàng và tôi đã học thêm một chút về Reshape ở cơ sở (mạnh mẽ chức năng nhưng đôi khi khó hiểu. –

+0

Tôi hoàn toàn đồng ý rằng nó có thể gây nhầm lẫn. Giống như Ben Bolker, tôi sử dụng để chỉ sử dụng reshape :: tan chảy. –

+0

chỉ trở lại đây (I muốn như vậy đã nói với bạn nếu ai đó chỉnh sửa câu trả lời của họ;...! chỉ là một gợi ý mà bạn thêm một bình luận khi bạn làm như vậy SO thông báo cho các áp phích) và tôi thích câu trả lời của bạn trước khi tôi thực sự thích nó bây giờ các chú thích là tuyệt vời Cảm ơn bạn –

3

Lạ lùng thay tôi don dường như không có những con số giống như bạn (mà tôi nên kể từ khi cả hai chúng tôi sử dụng set.seed(10)?) nhưng nếu không điều này dường như làm các trick:

library(reshape) #this might work with reshape2 as well, I haven't tried ... 
DF2 <- melt(DF,id.vars=1:2) 
## split 'activity.time' label into two separate variables 
DF3 <- cbind(DF2, 
      colsplit(as.character(DF2$variable),"\\.", 
         names=c("activity","time"))) 
## rename time, reorder factors: 
DF4 <- transform(DF3, 
       time=as.numeric(gsub("^T","",time)), 
       activity=factor(activity, 
        levels=c("work","play","talk","total")), 
       id=factor(id,levels=paste("x1",1:10,sep="."))) 
## reshape back to wide 
DF5 <- cast(subset(DF4,select=-variable),id+trt+time~activity) 
## reorder 
DF6 <- with(DF5,DF5[order(time,id),]) 

Nó phức tạp hơn câu trả lời của @ DWin nhưng có lẽ (?) Tổng quát hơn.

+0

Thank bạn Ben Tôi thêm cả phản ứng của bạn và Dwin của tôi (bây giờ hơn 200 trang) R ghi chú Cả hai phản ứng rất sâu sắc tùy thuộc vào tình hình +1 –

2

Nếu bạn thực sự không muốn "T" trong biến "thời gian" ở đầu ra, bạn có thể không thực hiện những điều sau đây không?

names(DF) = sub("T", "", names(DF)) 
reshape(DF, direction="long", varying=3:10) 

Hoặc, mà không thay đổi names(DF), bạn chỉ có thể thiết lập các tham số sep= bao gồm chữ "T":

reshape(DF, direction="long", varying=3:10, sep=".T") 

Tôi là một chút bối rối, mặc dù. Như Ben Bolker đã chỉ ra a in his comment, "mã bộ dữ liệu" của bạn không cung cấp số giống như những gì bạn có. Ngoài ra, đầu ra của DWin và mỏ phù hợp hoàn hảo, nhưng nó không khớp với đầu ra "vào" này mà bạn có trong câu hỏi ban đầu của bạn.

Tôi đã kiểm tra điều này bằng cách tạo một khung dữ liệu có tên "DWin" với kết quả của mình và một khung dữ liệu có tên là "của tôi" với kết quả của tôi và so sánh chúng bằng cách sử dụng DWin == mine.

Bạn có thể xác minh rằng đầu ra chúng tôi đã nhận thực sự là những gì bạn cần không?

+0

Có đầu ra bạn và DWin đã nhận là chính xác. set.seed. tôi xin lỗi. vĩ đại giải pháp. rất ít mã. –

0

Một cách khác để tiếp cận vấn đề đó đòi hỏi rất ít mã nhưng nhiều khả năng sẽ chậm hơn ,:

DF.1 <- DF[, 1:2] 
DF.2 <- DF[, 3:6] 
DF.3 <- DF[, 7:10] 

names(DF.2) <- names(DF.3) <- unlist(strsplit(names(DF.2), ".", fixed=T))[c(T,F)] 
time <- rep(1:2, each=nrow(DF.1)) 
data.frame(rbind(DF.1, DF.1), time, rbind(DF.2, DF.3)) 
4

Cách ngắn gọn nhất là sử dụng kết hợp với tidyr dplyr thư viện.

library(tidyr) 
library(dplyr) 
result <- DF %>% 
    # transfer to 'long' format 
    gather(loc, value, work.T1:total.`enter code here`T2) %>% 
    # separate the column into location and time 
    separate(loc, into = c('loc', 'time'), '\\.') %>% 
    # transfer to 'short' format 
    spread(loc, value) %>% 
    mutate(time = as.numeric(substr(time, 2, 2))) %>% 
    arrange(time) 

tidyr được thiết kế đặc biệt để làm cho dữ liệu gọn gàng.

+0

tôi sẽ không gọi ngắn gọn rằng so với các giải pháp khác. –

+1

Đây là vượt trội so với các giải pháp mà sử dụng 'reshape' - dễ đọc hơn nhờ vào kiểu dáng chức năng của nó (toán tử'%>% ') và trình diễn nhiều hơn nữa, tôi nghĩ, do các phần quan trọng được viết bằng C++. – GregT

+1

phần 'nhập mã ở đây' là gì? @Yingsen Mao – vashts85

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