[英]from 4d mat-lab array to a 2d matrix or data frame in R
我有一個最初是 Matlab.mat 文件的數據集。 當我將其導入到 R 時,
列表中具有 .mat 文件內容的元素之一似乎是一個多維數組(准確地說是 4d。
看起來像 num[1:41, 1:2400,1:60, 1:6]。 我知道這與在 2400 次試驗中變化的 41 種特征有關,因為 60 個人中的每一個在每次試驗中都會做出 6 種選擇中的一種。
由此我真正想要的只是一個二維矩陣或一個 dataframe,其中我可以有 41 列用於特征,一列用於試驗,一列用於人員 ID,一列用於存儲他們在該特定試驗中所做的選擇.
所以基本上每一行都會顯示所有 41 個特征的值、人員 ID、試驗 ID 和他們的選擇。 最終,我需要能夠在一個文件中共享它,例如 csv 或 txt。
有沒有一種有效的方法來做到這一點? 到目前為止,我的解決方案似乎真的很復雜,需要很多循環和 if 語句。 非常感謝
示例數據ary
,假設它在某種程度上代表了您的較大矩陣。
ary <- array(seq(prod(c(4,10,3,2))), dim = c(4,10,3,2))
ary
# , , 1, 1
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 5 9 13 17 21 25 29 33 37
# [2,] 2 6 10 14 18 22 26 30 34 38
# [3,] 3 7 11 15 19 23 27 31 35 39
# [4,] 4 8 12 16 20 24 28 32 36 40
# , , 2, 1
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 41 45 49 53 57 61 65 69 73 77
# [2,] 42 46 50 54 58 62 66 70 74 78
# [3,] 43 47 51 55 59 63 67 71 75 79
# [4,] 44 48 52 56 60 64 68 72 76 80
# , , 3, 1
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 81 85 89 93 97 101 105 109 113 117
# [2,] 82 86 90 94 98 102 106 110 114 118
# [3,] 83 87 91 95 99 103 107 111 115 119
# [4,] 84 88 92 96 100 104 108 112 116 120
# , , 1, 2
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 121 125 129 133 137 141 145 149 153 157
# [2,] 122 126 130 134 138 142 146 150 154 158
# [3,] 123 127 131 135 139 143 147 151 155 159
# [4,] 124 128 132 136 140 144 148 152 156 160
# , , 2, 2
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 161 165 169 173 177 181 185 189 193 197
# [2,] 162 166 170 174 178 182 186 190 194 198
# [3,] 163 167 171 175 179 183 187 191 195 199
# [4,] 164 168 172 176 180 184 188 192 196 200
# , , 3, 2
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 201 205 209 213 217 221 225 229 233 237
# [2,] 202 206 210 214 218 222 226 230 234 238
# [3,] 203 207 211 215 219 223 227 231 235 239
# [4,] 204 208 212 216 220 224 228 232 236 240
轉換它的三步過程:
tmp <- apply(ary, 3:4, function(z) as.data.frame(t(z)), simplify = FALSE)
eg <- do.call(expand.grid, lapply(dim(tmp), seq))
out <- do.call(rbind, Map(function(x, d3, d4) transform(x, dim3=d3, dim4=d4), c(tmp), eg[[1]], eg[[2]]))
dim(out)
# [1] 60 6
head(out)
# V1 V2 V3 V4 dim3 dim4
# 1 1 2 3 4 1 1
# 2 5 6 7 8 1 1
# 3 9 10 11 12 1 1
# 4 13 14 15 16 1 1
# 5 17 18 19 20 1 1
# 6 21 22 23 24 1 1
細節:
apply(ary, 3:4, ...)
將在 4d 數組的每個“平面”上應用 function。 3:4
表示第 3 維和第 4 維,前兩個維度(分別為行和列)保持不變。 在匿名 function 的單次調用中, z
是一個二維數組,例如ary[,,1,1]
。 t
將其轉置為 4 列寬,以便您可以在列維度中擁有您的特征。
eg
只是一種對 3rd 和 4th 維度進行編號的機制,以便我們可以記錄每個平面的來源。 這將返回一個幀,其中包含1:dim(ary)[3]
與1:dim(ary)[4]
的所有組合,並且順序與我們在執行c(tmp)
時得到的順序相同,保留編號的平面。 查看head(eg)
以了解它是如何計數的。
Map
在每個平面中分配eg
/dim4 值。
do.call(rbind, ...)
獲取data.frame
列表並生成單個幀。 它類似於rbind(out[[1]], out[[2]], out[[3]], ...)
,但其完成方式與存儲在out
中的平面數量無關元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.