2015-07-29 3 views
7

Я провел исследование, которое в ретроспективе (один живет, человек узнает :-)), похоже, генерирует многоуровневые данные. Теперь я пытаюсь реструктурировать набор данных от широкого до длинного, чтобы я мог анализировать его, используя, например, lme4.Как преобразовать широкий фреймворк данных в длинный фрейм данных для многоуровневой структуры с «четырехкратным вложением»?

При этом я сталкиваюсь с проблемой, которую я встречал несколько раз раньше, но для которой я никогда не находил хорошего решения. На этот раз я снова искал, но я, вероятно, использую неправильные ключевые слова - или эта проблема намного реже, чем я думал.

В принципе, в этом наборе данных переменные имена указывают, какие данные измерений собираются. Я попросил участников оценить (оценить) интервенции (может быть что-то действительно). Каждое вмешательство находится в одной из 6 областей поведения. Кроме того, участники оценивали каждое вмешательство либо, когда оно было представлено самостоятельно, либо одновременно с одним другим вмешательством, либо с двумя другими вмешательствами. Было три типа вмешательств, и все они были оценены до (t0), а после (t1) я представил им некоторую информацию.

Таким образом, по сути, у меня есть dataframe, которые могут регенерировать, как это:

### 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; 

Так с помощью head(wideData)[, 1:5] вы можете увидеть примерно то, что dataframe выглядит следующим образом:

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 

Теперь я хотите преобразовать эти данные в длинный фрейм данных с шестью переменными, например, «id», «measureMoment», «interactionType», «nrOfInterventionsSimultaneous», «behaviorDomain» и «оценка», где первая переменная обозначает участников, к которым запись принадлежит, las t - оценка (оценка, оценка, оценка), участники дали конкретное вмешательство, а четыре переменные между ними указывают, какое вмешательство оценивается точно.

Возможно, я могу написать некоторый «пользовательский» код только для этой проблемы, но я ожидаю, что у R есть что-то для этого ». Я играл вокруг с reshape2, например:

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

Но это не удается угадать нестационарные переменные:

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

Я боролся с этим несколько раз сейчас, и я не могу найти ответы в Интернете. И теперь мне действительно нужно двигаться дальше, поэтому я подумал, что попробую это как последнее усилие, прежде чем приступать к написанию чего-то выполненного на заказ :-)

Я был бы очень признателен за любые указатели, которые может дать любой !!!

+0

Что значение 'firstSecondOccurrenceVector'? – krlmlr

+0

Простите, это было из-за этого, прежде чем я немного разъяснил это! Это уже не важно :-) Извините за путаницу! – Matherion

+0

Не извиняйтесь. Вместо этого отредактируйте код, чтобы он запускался. –

ответ

8

Я думаю, ваша проблема может быть решена с помощью двухступенчатого подхода:

  1. расплавить ваши данные в длинный data.frame (или, как я, в длинном data.table)
  2. разделить variable колонку со всеми метки в отдельные столбцы для каждой требуемой переменной группировки.

Поскольку информация для этого находится в этикетках, это легко может быть достигнуто с помощью tstrsplit функции из data.table пакета.

Это то, что вы могли бы искать:

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

Результат:

> 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 

В качестве альтернативы data.table, вы можете также разделить variable столбец с функцией cSplit пакета splitstackshape (после этого вам придется переименовать результирующие переменные столбцы):

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

или tidyr:

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

Это замечательно, спасибо! Именно то, что мне нужно. Также спасибо, что указали мне на data.table, это выглядит великолепно! Большое спасибо!!! – Matherion

 Смежные вопросы

  • Нет связанных вопросов^_^