2015-07-29 20 views
7

Tôi đã tiến hành một nghiên cứu mà, trong hồi tưởng (một cuộc sống, một học :-)) xuất hiện để tạo ra dữ liệu đa cấp. Bây giờ tôi đang cố gắng cơ cấu lại tập dữ liệu từ rộng đến dài để tôi có thể phân tích nó bằng cách sử dụng ví dụ: lme4.Làm cách nào để chuyển đổi một khung dữ liệu rộng sang một khung dữ liệu dài cho cấu trúc đa cấp với 'tổ hợp bốn lần'?

Khi làm như vậy, tôi gặp phải một thử thách, mà tôi đã gặp phải vài lần trước đây, nhưng tôi chưa bao giờ tìm được giải pháp tốt. Tôi đã tìm kiếm lần nữa, nhưng tôi có thể sử dụng các từ khóa sai - hoặc vấn đề này là hiếm hơn nhiều so với tôi nghĩ.

Về cơ bản, trong tập dữ liệu này, variablenames cho biết dữ liệu đo được thu thập. Tôi yêu cầu những người tham gia vào các biện pháp can thiệp (tỷ lệ) (có thể là bất cứ điều gì thực sự). Mỗi can thiệp là một trong 6 lĩnh vực hành vi. Ngoài ra, những người tham gia đánh giá từng can thiệp hoặc khi nó được trình bày riêng, hoặc đồng thời với một can thiệp khác, hoặc với hai can thiệp khác. Có ba loại can thiệp, và tất cả chúng đều được đánh giá trước (t0) và sau (t1) tôi trình bày chúng với một số thông tin.

Vì vậy, trên thực tế, tôi có một dataframe có thể được tái sinh như thế này:

### Elements of the variable names 
measurementMomentsVector <- c("t0", "t1"); 
interventionTypesVector <- c("fear", "know", "scd"); 
nrOfInterventionsSimultaneouslyVector <- c(1, 2, 3); 
behaviorDomainsVector <- c("diet", "pox", "alc", "smoking", "traff", "adh"); 

### Generate a vector with all variable names 
variableNames <- 
    apply(expand.grid(measurementMomentsVector, 
        interventionTypesVector, 
        nrOfInterventionsSimultaneouslyVector, 
        behaviorDomainsVector), 
     1, paste0, collapse="_"); 

### Generate 5 'participants' worth of data 
wideData <- data.frame(matrix(rnorm(5*length(variableNames)), nrow=5)); 

### Assign names 
names(wideData) <- variableNames; 

### Add unique id variable for every participants 
wideData$id <- 1:5; 

Vì vậy, sử dụng head(wideData)[, 1:5] bạn có thể thấy khoảng những gì dataframe trông giống như:

t0_fear_1_diet t1_fear_1_diet t0_know_1_diet t1_know_1_diet t0_scd_1_diet 
1  -0.9338191  0.9747453  1.0069036  0.3500103 -0.844699708 
2  0.8921867  1.3687834  -1.2005791  0.2747955 1.316768219 
3  1.6200200  0.5245470  -1.2910586  1.3211912 -0.174795144 
4  0.1543738  0.7535642  0.4726131  -0.3464789 -0.009190702 
5  -1.3676692  -0.4491574  -2.0902003  -0.3484678 -2.537501824 

Bây giờ, tôi muốn chuyển đổi dữ liệu này thành một khung dữ liệu dài, với 6 biến, ví dụ 'id', 'measurementMoment', 'interventionType', 'nrOfInterventionsSimultaneously', 'behaviorDomain' và 'evaluation', trong đó biến đầu tiên biểu thị những người tham gia một kỷ lục thuộc về, las t biến là điểm số (xếp hạng, cấp lớp, đánh giá) những người tham gia đã đưa ra một sự can thiệp cụ thể và bốn biến số ở giữa cho biết sự can thiệp nào đang được đánh giá chính xác.

Tôi có thể viết một số mã 'tùy chỉnh' chỉ cho vấn đề này, nhưng tôi hy vọng R 'có cái gì đó cho điều này'. Tôi đã được chơi đùa với reshape2, ví dụ:

longData <- reshape(wideData, varying=1:(ncol(wideData)-1), 
        idvar="id", 
        sep="_", direction="long") 

Nhưng nó không quản lý để đoán các biến thiên theo thời gian:

Error in guess(varying) : 
    failed to guess time-varying variables from their names 

Tôi đã đấu tranh với điều này một vài lần bây giờ, và tôi không tìm thấy câu trả lời trực tuyến. Và bây giờ tôi thực sự cần phải tiếp tục, vì vậy tôi nghĩ rằng tôi sẽ cố gắng này như một nỗ lực cuối cùng trước khi sử dụng để viết một cái gì đó tùy chỉnh-thực hiện :-)

Tôi rất nhiều sẽ đánh giá cao bất kỳ con trỏ ai cũng có thể cho !!!

+0

giá trị của 'firstSecondOccurrenceVector' là gì? – krlmlr

+0

Xin lỗi, đó là phần còn lại từ trước khi tôi làm rõ nó một chút! Nó không còn quan trọng :-) Xin lỗi vì sự nhầm lẫn! – Matherion

+0

Đừng xin lỗi. Thay vào đó hãy chỉnh sửa mã để nó chạy. –

Trả lời

8

Tôi nghĩ vấn đề của bạn có thể được giải quyết với một cách tiếp cận hai bước:

  1. tan chảy dữ liệu của bạn vào một lâu data.frame (hoặc như tôi đã làm, trong một lâu data.table)
  2. chia cột variable với tất cả các nhãn thành các cột riêng biệt cho mỗi biến nhóm được yêu cầu.

Vì thông tin cho điều này nằm trong nhãn, điều này có thể dễ dàng đạt được với hàm tstrsplit từ gói data.table.

Đây là những gì bạn có thể tìm kiếm:

library(data.table) 
longData <- melt(setDT(wideData), id.vars="id") 
longData[, c("moment", "intervention", "number", "behavior") := 
       tstrsplit(variable, "_", type.convert = TRUE) 
     ][, variable:=NULL] 

kết quả:

> head(longData,15) 
    id  value moment intervention number behavior 
1: 1 -0.07747254  t0   fear  1  diet 
2: 2 -0.76207379  t0   fear  1  diet 
3: 3 1.15501244  t0   fear  1  diet 
4: 4 1.24792369  t0   fear  1  diet 
5: 5 -0.28226121  t0   fear  1  diet 
6: 1 -1.04875354  t1   fear  1  diet 
7: 2 -0.91436882  t1   fear  1  diet 
8: 3 0.72863487  t1   fear  1  diet 
9: 4 0.10934261  t1   fear  1  diet 
10: 5 -0.06093002  t1   fear  1  diet 
11: 1 -0.70725760  t0   know  1  diet 
12: 2 1.06309003  t0   know  1  diet 
13: 3 0.89501164  t0   know  1  diet 
14: 4 1.48148316  t0   know  1  diet 
15: 5 0.22086835  t0   know  1  diet 

Để thay thế cho data.table, bạn cũng có thể chia cột variable với cSplit chức năng của gói splitstackshape (bạn sẽ phải đổi tên các cột biến kết quả sau đó):

library(splitstackshape) 
longData <- cSplit(longData, sep="_", "variable", "wide", type.convert=TRUE) 
names(longData) <- c("id","value","moment","intervention","number","behavior") 

hoặc với tidyr:

library(tidyr) 
separate(longData, variable, c("moment", "intervention", "number", "behavior"), sep="_", remove=TRUE) 
+0

Điều này thật tuyệt vời, cảm ơn bạn! Chính xác những gì tôi cần. Ngoài ra cảm ơn bạn đã chỉ cho tôi theo hướng data.table, có vẻ tuyệt vời! Cảm ơn nhiều!!! – Matherion

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