2013-02-25 2 views
2

Я пытаюсь (эффективно) переставить dataframe в R.Перегруппировка dataframes в R

Мои данные экспериментальные данные, собранные в течение четырех различных экспериментов из двух популяций участников (1 или 0, то есть заболевания и контрольной группы) ,

Пример dataframe:

Subject type Experiment 1 Experiment 2 Experiment 3 Experiment 4 
      0    4.6    2.5    1.4    5.3 
      0    4.7    2.4    1.8    5.1 
      1    3.5    1.2    5.6    7.5 
      1    3.8    1.7    6.2    8.1 

Я хотел бы изменить свою dataframe так, что она структурирована следующим образом (по причине того, что делает его легче для меня, чтобы запускать функции на данных, когда они структурированы как это в R):

Subject type Experiment Measure 
      0    1  4.6 
      0    2  2.5 
      0    3  1.4 
      0    4  5.3 
      0    1  4.7 
      0    2  2.4 
      0    3  1.8 
      0    4  5.1 
      1    1  3.5 
      1    2  1.2 
      1    3  5.6 
      1    4  7.5 
      1    1  3.8 
      1    2  1.7 
      1    3  6.2 
      1    4  8.1 

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

В любом случае - вопрос в том, что является наиболее эффективным способом преобразования данных в виде данных? В настоящее время я делаю это так:

# Input dframe1 
dframe1 <- structure(list(subject_type = c(0L, 0L, 1L, 1L), experiment_1 = c(4.6, 
4.7, 3.5, 3.8), experiment_2 = c(2.5, 2.4, 1.2, 1.7), experiment_3 = c(1.4, 
1.8, 5.6, 6.2), experiment_4 = c(5.3, 5.1, 7.5, 8.1)), .Names = c("subject_type", 
"experiment_1", "experiment_2", "experiment_3", "experiment_4" 
), class = "data.frame", row.names = c(NA, -4L)) 

# Create a matrix 
temporary_matrix <- matrix(ncol=3, nrow=nrow(dframe1) * 4) 
colnames(temporary_matrix) <- c("subject_type","experiment","measure") 

# Rearrange dframe1 so that a different measure is in each column 
for(i in 1:nrow(dframe1)) { 
    temporary_matrix[i*4-3,"subject_type"] <- dframe1$subject_type[i] 
    temporary_matrix[i*4-3,"experiment"] <- 1 
    temporary_matrix[i*4-3,"measure"] <- dframe1$experiment_1[i] 
    temporary_matrix[i*4-2,"subject_type"] <- dframe1$subject_type[i] 
    temporary_matrix[i*4-2,"experiment"] <- 2 
    temporary_matrix[i*4-2,"measure"] <- dframe1$experiment_2[i] 
    temporary_matrix[i*4-1,"subject_type"] <- dframe1$subject_type[i] 
    temporary_matrix[i*4-1,"experiment"] <- 3 
    temporary_matrix[i*4-1,"measure"] <- dframe1$experiment_3[i] 
    temporary_matrix[i*4-0,"subject_type"] <- dframe1$subject_type[i] 
    temporary_matrix[i*4-0,"experiment"] <- 4 
    temporary_matrix[i*4-0,"measure"] <- dframe1$experiment_4[i] 
} 

# Convert matrix to a data frame 
dframe2 <- data.frame(temporary_matrix) 

# NOTE: For some reason, this has to be converted back into a double (at some point above it becomes a factor) 
dframe2$measure <- as.double(as.character(dframe2$measure)) 

Конечно есть лучший способ сделать это ?!

+5

Посмотрите на упаковке reshape2 или изменить форму в базе R. –

+0

+1! спасибо за этот полный вопрос, он содержит: 1-Что вы хотите сделать? Что вы пробовали 3 воспроизводимый пример. – agstudy

ответ

5

Использование пакета reshape2, это очень просто.

library(reshape2) 

# assuming your data.frame is called `dat` 
melt(dat, id.vars=c("Subject type")) 

вы можете сделать это perrtier, если вы хотите:

newdat <- melt(dat, id.vars=c("Subject type"), variable.name="Experiment", value.name="Measure") 

# remove "experiment " from the names, and convert to numeric 
newdat$Experiment <- as.numeric(gsub("Experiment\\s*", "", as.character(newdat$Experiment))) 
4

Base reshape метод:

Получить данные:

dframe1 <- structure(list(subject_type = c(0L, 0L, 1L, 1L), experiment_1 = c(4.6, 
4.7, 3.5, 3.8), experiment_2 = c(2.5, 2.4, 1.2, 1.7), experiment_3 = c(1.4, 
1.8, 5.6, 6.2), experiment_4 = c(5.3, 5.1, 7.5, 8.1)), .Names = c("subject_type", 
"experiment_1", "experiment_2", "experiment_3", "experiment_4" 
), class = "data.frame", row.names = c(NA, -4L)) 

Установить переменные для укладки:

expandvars <- paste('experiment',1:4,sep='_') 

Измените форму!

dfrm1res <- reshape(
        dframe1, 
        idvar="subject_type", 
        varying=list(expandvars), 
        v.names=c("value"), 
        direction="long", 
        new.row.names=1:16 
        ) 

Результат:

> dfrm1res 
    subject_type time value 
1    0 1 4.6 
2    0 1 4.7 
3    1 1 3.5 
4    1 1 3.8 
5    0 2 2.5 
6    0 2 2.4 
7    1 2 1.2 
8    1 2 1.7 
9    0 3 1.4 
10   0 3 1.8 
11   1 3 5.6 
12   1 3 6.2 
13   0 4 5.3 
14   0 4 5.1 
15   1 4 7.5 
16   1 4 8.1 
+0

+1 для решения reshpae! Могу я предложить 'expandvars <- paste ('experiment', 1: 4, sep = '_')' – agstudy

+0

@agstudy - вы можете, у вас есть, и я отредактировал. – thelatemail

4
data.frame(subject_type=dframe1$subject_type, stack(dframe1[2:5]) ) 
    subject_type values   ind 
1    0 4.6 experiment_1 
2    0 4.7 experiment_1 
3    1 3.5 experiment_1 
4    1 3.8 experiment_1 
5    0 2.5 experiment_2 
6    0 2.4 experiment_2 
7    1 1.2 experiment_2 
8    1 1.7 experiment_2 
9    0 1.4 experiment_3 
10   0 1.8 experiment_3 
11   1 5.6 experiment_3 
12   1 6.2 experiment_3 
13   0 5.3 experiment_4 
14   0 5.1 experiment_4 
15   1 7.5 experiment_4 
16   1 8.1 experiment_4 

Или используйте базовый reshape (хотя кажется, мои предпочтения отличаются от использования thelatemal о ней.):

dframe1$subject=1:4 
reshape(dframe1, direction="long", idvar=c("subject_type", "subject"), 
       varying=2:5, sep="_", v.names="exp_value") 
#-------------------------- 
     subject_type subject time exp_value 
0.1.1   0  1 1  4.6 
0.2.1   0  2 1  4.7 
1.3.1   1  3 1  3.5 
1.4.1   1  4 1  3.8 
0.1.2   0  1 2  2.5 
0.2.2   0  2 2  2.4 
1.3.2   1  3 2  1.2 
1.4.2   1  4 2  1.7 
0.1.3   0  1 3  1.4 
0.2.3   0  2 3  1.8 
1.3.3   1  3 3  5.6 
1.4.3   1  4 3  6.2 
0.1.4   0  1 4  5.3 
0.2.4   0  2 4  5.1 
1.3.4   1  3 4  7.5 
1.4.4   1  4 4  8.1 
+0

Хорошее использование 'stack'! –

+0

+1! Улыбка! Хорошее использование стека и утилизации! – agstudy

+0

Я думаю, что это оригинальная цель стека. –

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