我有一个312x2矩阵,代表个别科目回答的问题数目(第2栏)(第1栏) e.g。
x =
40 56
41 56
42 176
43 176
44 116
45 56
46 56
47 116
48 56
49 56
50 116
有些参与者不止一次回答问卷,我想将他们的数据分成额外的栏目。
即。参与者43完成了3次 - 一次56个问题,两次60个问题。
因此,我想将他们的数据分成3列,最后得到:
x =
40 56
41 56
42 56 60 60
43 56 60 60
44 56 60
...etc
然后我会用NaN填补空白,这样我就可以找出每份调查问卷所回答的平均问题。
答案 0 :(得分:2)
这不是最优雅的解决方案,但它可以相对简单地完成工作:
x = [40 56;41 56;42 176;43 176;44 116;45 56;46 56;47 116;48 56;49 56;50 116];
a=x(:,2);
newData=[];
for i=1:size(a,1)
if a(i)==56
newData=vertcat(newData,[56 NaN NaN]);
elseif a(i)==116
newData=vertcat(newData,[56 60 NaN]);
elseif a(i)==176
newData=vertcat(newData,[56 60 60]);
end
end
Data = horzcat(x(:,1),newData)
命令窗口:
Data =
40 56 NaN NaN
41 56 NaN NaN
42 56 60 60
43 56 60 60
44 56 60 NaN
45 56 NaN NaN
46 56 NaN NaN
47 56 60 NaN
48 56 NaN NaN
49 56 NaN NaN
50 56 60 NaN
答案 1 :(得分:1)
最好使用cell arrays来存储最终输出,因为每行可能包含不同数量的元素。
这是一个简短的解决方案,可以为您提供所需的结果:
C = mat2cell(x, ones(1, size(x, 1)), 2);
C(ismember(x(:, 1), cellfun(@(z)z(1), y))) = y;
其中x
是问题中描述的原始数据数组,而y
是一个包含新行(正如您所称, split )的单元格数组替换x
。
这是一个类似于问题中给出的简短示例:
%// Generate sample data
x = [40 56; 41 56; 42 176; 43 176; 44 116; 45 56];
y = {[43 56 60 60]; [44 56 60]};
%// Replace rows in x with matching rows in y
C = mat2cell(x, ones(1, size(x, 1)), 2);
C(ismember(x(:, 1), cellfun(@(z)z(1), y))) = y;
结果是一个新的单元格数组:
C =
[40 56]
[41 56]
[42 176]
[43 56 60 60]
[44 56 60]
[45 56]
要计算每个问卷回答的平均问题,请使用cellfun
迭代单元格:
m = cellfun(@(x)mean(x(2:end)), C)
这个例子产生:
m =
56.0000
56.0000
176.0000
58.6667
58.0000
56.0000
答案 2 :(得分:0)
以下将实现您的需求:
B = unique(A(:,1));
m = max(hist(A(:,1),B));
B = [B, nan(numel(B),m)];
for ii=1:size(B,1)
jj = (A==B(ii,1));
B(ii,2:end) = [A(jj(:,1),2)', nan(1,m-sum(sum(jj(:,1))))];
end
输入:
A =
53 83
84 76
52 99
53 83
76 90
54 73
91 72
91 92
86 54
57 56
结果将是:
B =
52 99 NaN
53 83 83
54 73 NaN
57 56 NaN
76 90 NaN
84 76 NaN
86 54 NaN
91 72 92
答案 3 :(得分:0)
当您指定超出当前矩阵范围的内容时,MATLAB会自动为您扩展矩阵:
>> a = [
40 56
41 56
42 176
43 176
44 116
45 56
46 56
47 116
48 56
49 56
50 116];
>> a(3,3) = 60
a =
40 56 0
41 56 0
42 176 60
43 176 0
44 116 0
45 56 0
46 56 0
47 116 0
48 56 0
49 56 0
50 116 0
默认操作是使用零填充(而不是NaN
s)。如果您可以合理地期望永远不会成为任何回答0个问题的参与者,那么您可以做到
>> a(a==0) = NaN;
>> M = nanmean(a(:,2:end),2);
获得平均值。
如果您不能指望这一点(或者您没有/想要依赖统计工具箱来使用nanmean
)那么您可以编写一些小函数来执行您想要的操作:
function new_a = addQsAnswered(old_a, QsAnswered)
new_a = old_a;
for ii = 1:size(QsAnswered,1)
inds = (new_a(:,1) == QsAnswered(ii,1));
if sum(isnan(new_a(inds,:))) < size(QsAnswered(:,2:end),2)
new_a = [new_a NaN(size(new_a,1),1)]; %#ok
end
new_a(inds,isnan(new_a(inds,:))) = QsAnswered(ii,2:end);
end
end
function M = getParticipantMeans(a)
M = zeros(size(a,1),1);
for ii = 1:size(a,1)
as = a(ii,2:end);
as = as(~isnan(as));
M(ii) = sum(as)/numel(as);
end
end
示例:
>> addQsAnswered(a, [46 78 90; 49 60 78])
ans =
40 56 NaN NaN
41 56 NaN NaN
42 176 60 NaN
43 176 NaN NaN
44 116 NaN NaN
45 56 NaN NaN
46 56 78 90
47 116 NaN NaN
48 56 NaN NaN
49 56 60 78
50 116 NaN NaN
>> getParticipantMeans(new_a)
ans =
5.600000000000000e+001
5.600000000000000e+001
1.180000000000000e+002
1.760000000000000e+002
1.160000000000000e+002
5.600000000000000e+001
7.466666666666667e+001
1.160000000000000e+002
5.600000000000000e+001
6.466666666666667e+001
1.160000000000000e+002