0

I've been stumped trying to create an if,else loop that transposes the following:

Subject: Date: Result:
AAA 02/01/12 10
AAA 02/02/12 12
AAA 02/03/12 14
BBB 02/01/12 25
BBB 02/02/12 26
BBB 02/03/12 27
CCC 01/01/12 66
CCC 01/02/12 70
CCC 01/03/12 75

I desire the information to be transposed across columns as depicted below:

SUBJECT 01/01/12 01/02/12 01/03/12 02/01/12 02/02/12 02/03/12
AAA RESULT
BBB RESULT
CCC RESULT

There should only be one date per column and one subject per row. The result will match its respective subject and placed in its appropriate cell. The data can consist anywhere from a few subject to thousands of subjects, dates, and results. Some results may consist of non numerical values (NaN). Also, the subjects and dates may me in any random order and subjects may consist of numeric and string characters.

UPDATE @amro & superbest

If I had a text file with the date format:800317==mar/17/1980, How would I import this and modify the codes you've written? THanks again.

4

2 回答 2

2

如果您将数据存储在数据集数组对象中,那么unstack方法就是您要查找的方法(有时称为高到宽转换)。


我制定了一个简单的示例,展示了如何在没有数据集类的情况下执行此操作:

%# cell array: subjects, dates, values
data = {
    'AA' '2012-05-01' 0.1
    'AA' '2012-05-03' 0.2
    'BB' '2012-05-02' 0.3
    'CC' '2012-05-01' 0.4
    'CC' '2012-05-02' 0.5
    'CC' '2012-05-03' 0.6
};

[subjects,~,subjectsMap] = unique(data(:,1));
[dates,~,datesMap] = unique(data(:,2));
M = nan(numel(subjects),numel(dates));
for i=1:numel(subjects)
    %# get all rows with subject == subject_i
    rIdx = (subjectsMap == i);
    %# fill values at this row for the specified columns
    M(i,datesMap(rIdx)) = cell2mat(data(rIdx,3));
end

D = cell(size(M)+1);
D(2:end,2:end) = num2cell(M);       %# fill values
D(1,2:end) = dates;                 %# column headers
D(2:end,1) = subjects;              %# row headers

这是转换之前(高)和之后(宽)的数据:

>> data
data = 
    'AA'    '2012-05-01'    [0.1]
    'AA'    '2012-05-03'    [0.2]
    'BB'    '2012-05-02'    [0.3]
    'CC'    '2012-05-01'    [0.4]
    'CC'    '2012-05-02'    [0.5]
    'CC'    '2012-05-03'    [0.6]

>> D
D = 
      []    '2012-05-01'    '2012-05-02'    '2012-05-03'
    'AA'    [       0.1]    [       NaN]    [       0.2]
    'BB'    [       NaN]    [       0.3]    [       NaN]
    'CC'    [       0.4]    [       0.5]    [       0.6]
于 2012-05-28T07:54:03.103 回答
1

这是一个应该做你想做的脚本:

% Clean up
clc
clear

% Hardcoded example input
input = {
    'AAA'    '02/01/12'    10
    'AAA'    '02/02/12'    12
    'AAA'    '02/03/12'    14
    'BBB'    '02/01/12'    25
    'BBB'    '02/02/12'    26
    'BBB'    '02/03/12'    27
    'CCC'    '01/01/12'    66
    'CCC'    '01/02/12'    70
    'CCC'    '01/03/12'    75
    };

% Figure out how many rows and columns there will be
header_row = unique(input(:, 2));
header_col = unique(input(:, 1));

% Pre-allocation for better performance
output = cell(length(header_col), length(header_row));

% Rearrange the array
for i = 1:size(input, 1)
    % Find to which date and subject this element belongs
    subject = find(strcmp(header_col, input{i, 1}));
    date = find(strcmp(header_row, input{i, 2}));

    % Put the value in the appropriate slot
    output{subject, date} = input{i, 3};
end

% Add header columns and rows and print the result
result = [['SUBJECT' header_row']; [header_col output]];
于 2012-05-28T08:42:28.813 回答