2

Rでデータフレームを(効率的に)再配置しようとしています.

私のデータは、参加者の 2 つの集団 (1 または 0、つまり疾患グループと対照グループ) から 4 つの異なる実験で収集された実験データです。

データフレームの例:

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

次のように構造化されるようにデータフレームを再配置したいと思います (理由は、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

ご覧のとおり、各サブジェクトが 4 行を占めるようになりました。各行は、単一の被験者ではなく、単一の測定に関連するようになりました。これは (少なくとも今のところ) 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))

確かにこれを行うより良い方法がありますか?!

4

3 に答える 3

5

reshape2パッケージを使用すると、これは非常に簡単です。

library(reshape2)

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

必要に応じて、より詳細にすることができます。

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)))
于 2013-02-25T01:23:44.730 に答える
4

ベース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
于 2013-02-25T01:54:23.717 に答える
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

または base を使用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
于 2013-02-25T02:03:29.263 に答える