将列数组转换为交替行

时间:2017-02-26 07:46:47

标签: r matlab matrix coordinates reshape

从以下格式......(x1-x27y1-y27是数字x,y坐标,需要移动到单个行,每个subj。)

Subj    X   Y
1   x1  y1
1   x2  y2
1   x3  y3
1   x4  y4
1   x5  y5
1   x6  y6
1   x7  y7
1   x8  y8
1   x9  y9
2   x10 y10
2   x11 y11
2   x12 y12
2   x13 y13
2   x14 y14
2   x15 y15
2   x16 y16
2   x17 y17
2   x18 y18
3   x19 y19
3   x20 y20
3   x21 y21
3   x22 y22
3   x23 y23
3   x24 y24
3   x25 y25
3   x26 y26
3   x27 y27

格式如下:

Subj    X   Y                                                               
1   x1  y1  x2  y2  x3  y3  x4  y4  x5  y5  x6  y6  x7  y7  x8  y8  x9  y9
2   x10 y10 x11 y11 x12 y12 x13 y13 x14 y14 x15 y15 x16 y16 x17 y17 x18 y18
3   x19 y19 x20 y20 x21 y21 x22 y22 x23 y23 x24 y24 x25 y25 x26 y26 x27 y27

我想使用R或MATLAB R2016a来做到这一点。

4 个答案:

答案 0 :(得分:1)

这是在MATLAB R2016b中实现它的一种方法:

in = [repelem(1:3,9).' ...
      strcat(string('x'), string((1:27).')) ...
      strcat(string('y'), string((1:27).'))];

u = unique(in(:,1)); 
out = [u reshape(in(:,2:3).', [], numel(u)).'];

在旧版本中,您可能正在使用单元格数组而不是string个变量(除非x1...y27实际上是数字,在这种情况下,常规数组会这样做。)

答案 1 :(得分:0)

这是Matlab上的另一种方式,使用线性索引(假设主题数是正整数):

data = [repelem([1 2 4],4).' randi(50,12,2)]; % some data...
%% code start here: %%
unsubj = unique(data(:,1)); % get unique subjucts numbers
coordsN = numel(data(:,2:end))/numel(unsubj); % no. data values per subject
% linear indices for the data
coord_ind = bsxfun(@plus,unsubj,0:max(unsubj):coordsN*max(unsubj)-1).';
output = zeros(max(unsubj),coordsN); % initialize the output
output(coord_ind(:)) = data(:,2:3).'; % fill the output matrix
subjT(unsubj) = unsubj; % make the first column
output = [subjT.' output]; % add the subect column

此解决方案的优势在于它还可以将非连续行号作为主题的输入(如上面代码中的示例所示)。

答案 2 :(得分:0)

R中,您可以使用data.table进行重塑。这是最灵活的方法,因为不同的Subj的数量都不受限制,每个Subj的坐标数也不受限制。

library(data.table)
DTM <- melt(DT, id.var = "Subj")
dcast(DTM, Subj ~ rowid(Subj, variable) + variable, value.var = "value")
#   Subj 1_X 1_Y 2_X 2_Y 3_X 3_Y 4_X 4_Y 5_X 5_Y 6_X 6_Y 7_X 7_Y 8_X 8_Y 9_X 9_Y
#1:    1  x1  y1  x2  y2  x3  y3  x4  y4  x5  y5  x6  y6  x7  y7  x8  y8  x9  y9
#2:    2 x10 y10 x11 y11 x12 y12 x13 y13 x14 y14 x15 y15 x16 y16 x17 y17 x18 y18
#3:    3 x19 y19 x20 y20 x21 y21 x22 y22 x23 y23 x24 y24 x25 y25 x26 y26 x27 y27

首先,DT从宽格式转换为长格式,以便所有坐标都是 在value列中。 variable列包含&#34; X&#34;和&#34; Y&#34;指示原始列名称取值。

然后,熔融数据DTM从长到宽整形。从而,在运行中创建行索引,其对应于原始Subj中的每个DT的行号。列首先按此行索引排序,然后按变量名称排序,以确保XY值以交替顺序显示。

如果每个组的坐标数不同,则缺少的列值将用NA填充。

这可以合并为一行代码:

dcast(melt(DT, id.var = "Subj"), Subj ~ rowid(Subj, variable) + variable, value.var = "value")

请注意,还有另一种使用matrix的方法,但这需要更多代码行,并且由于所有Subj的坐标对数必须相同,因此灵活性较低。

数据

DT <- structure(list(Subj = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L), X = c("x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", 
"x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", 
"x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27"
), Y = c("y1", "y2", "y3", "y4", "y5", "y6", "y7", "y8", "y9", 
"y10", "y11", "y12", "y13", "y14", "y15", "y16", "y17", "y18", 
"y19", "y20", "y21", "y22", "y23", "y24", "y25", "y26", "y27"
)), .Names = c("Subj", "X", "Y"), row.names = c(NA, -27L), class = c("data.table", 
"data.frame"))

答案 3 :(得分:-1)

使用concatenation和find(),这很简单。以下是示例代码:

clc;clear;close;

SubjectMatrix=[
1  ,11  ,21;
1  ,12  ,22;
1  ,13  ,23;
1  ,14  ,24;
1  ,15  ,25;
1  ,16  ,26;
1  ,17  ,27;
1  ,18  ,28;
1  ,19  ,29;
2  ,110 ,210;
2  ,111 ,211;
2  ,112 ,212;
2  ,113 ,213;
2  ,114 ,214;
2  ,115 ,215;
2  ,116 ,216;
2  ,117 ,217;
2  ,118 ,218;
3  ,119 ,219;
3  ,120 ,220;
3  ,121 ,221;
3  ,122 ,222;
3  ,123 ,223;
3  ,124 ,224;
3  ,125 ,225;
3  ,126 ,226;
3  ,127 ,227; ];

Subject1=[];
Subject2=[];
Subject3=[];

Matcoor=find(SubjectMatrix(:,1)==1);
for i=1:length(Matcoor)
    Subject1=[Subject1 SubjectMatrix(Matcoor(i),2:3)];%concatenation
end

Matcoor=find(SubjectMatrix(:,1)==2);
for i=1:length(Matcoor)
    Subject2=[Subject2 SubjectMatrix(Matcoor(i),2:3)];%concatenation
end

Matcoor=find(SubjectMatrix(:,1)==3);
for i=1:length(Matcoor)
    Subject3=[Subject3 SubjectMatrix(Matcoor(i),2:3)];%concatenation
end