티스토리 뷰

지난 글에서 추가된 기능
- 함수화 하였음 (chat_race.m)
- 날짜 단위로 끊는 기능 (dayChunk)
- 여전히 개수 단위로도 끊을 수 있음 (NChunk)
- 제외할 username 지정 가능 (nameExclude)
- 어디서 끊을지 정하지 않으면 기본값은 7일 단위로 끊는 것
% 10일 단위로 끊기
chat_race(file, dayChunk=10)
% 1000개 단위로 끊기, "방장봇" 제외
chat_race(file, NChunk=1000, nameExclude="방장봇")
% 7일 단위로 끊기
chat_race(file)
전체 코드
function chat_race(file, opts)
arguments
file
opts.dayChunk (1, 1) = 7
opts.NChunk (1, 1)
opts.nameExclude = []
end
%% 텍스트 읽어오기
fid = fopen(file);
s = fscanf(fid, '%c');
fclose(fid);
s = split(s, newline);
s = string(s);
%% 처음 등장하는 날짜 이전은 다 지우기
pattern_datestart = '^--------------- ';
while true
if isempty(regexp(s(1), pattern_datestart, 'once'))
s(1) = [];
else
break
end
end
%% 날짜가 찾아지면, 그 줄은 지우고 다음 줄부터 닉 옆에 날짜랑 시간 쓰기
pattern_name = '^\[(.*?)\] \[오';
pattern_time = '(오전|오후) \d{1,2}:\d{2}';
pattern_date = '(?<year>\d{4})년 (?<month>\d{1,2})월 (?<day>\d{1,2})일';
for i = 1:length(s)
tokens = regexp(s(i), pattern_date, 'names');
username = regexp(s(i), pattern_name, 'tokens');
if ~isempty(regexp(s(i), pattern_datestart, 'once')) && ...
~isempty(tokens)
dt = join(struct2array(tokens), '-');
s(i, :) = "";
elseif ~isempty(username)
s(i, 3) = regexp(s(i, 1), pattern_time, 'match', 'once');
s(i, 1) = username;
s(i, 2) = dt;
else
s(i, :) = "";
end
end
s(s(:, 1)=="", :) = [];
%% 제외할 닉네임 제외하기
for i = 1:length(opts.nameExclude)
s(s(:,1) == opts.nameExclude(i), :) = [];
end
%% 테이블로 만들고 datetime 추가하기
s = table(s(:, 1), s(:, 2), s(:, 3), 'VariableNames', {'username', 'date', 'time'});
s.datetime = datetime(s.date + " " + s.time, ...
InputFormat='yyyy-M-d a h:mm', locale='ko_KR', ...
Format='yyyy-MM-dd HH:mm:ss');
s.date = datetime(s.date, 'InputFormat', 'yyyy-M-d');
firstday = s.date(1);
%% username 한번씩만 남기기
allNames = unique(s.username, 'stable');
%% Chunk 나누기
if isfield(opts, 'NChunk')
iEnd = (1:ceil(height(s)/opts.NChunk))' * opts.NChunk;
iStart = iEnd - opts.NChunk + 1;
iEnd(end) = height(s);
varnames = "~" + iEnd;
else
lastday = s.date(end);
edges = (firstday:caldays(opts.dayChunk):(lastday + caldays(opts.dayChunk)))';
B = discretize(s.date, edges);
iStart = find([true; diff(B) ~= 0]);
iEnd = [iStart(2:end)-1; size(s, 1)];
varnames = string(edges(1:end-1));
end
chunkIdx = [iStart iEnd];
%% ready, get set
raceTable = table(allNames, 'VariableNames', {'Username'});
for i = 1:size(chunkIdx, 1)
chatCounts = countcats(...
categorical(s.username(chunkIdx(i, 1):chunkIdx(i, 2)),...
raceTable.Username));
raceTable.(varnames(i)) = chatCounts(:);
end
raceTable(:, 2:end) = cumsum(raceTable(:, 2:end), 2);
if isfield(opts, 'NChunk')
% 개수로 끊었을 때
cuts = string(raceTable.Properties.VariableNames(2:end)');
if opts.NChunk >= 1000
cuts = ceil(double(cuts.extractAfter("~"))/1000);
timeStamp = datetime(cuts, 1, 1, Format="y'k'");
else
cuts = ceil(double(cuts.extractAfter("~")));
timeStamp = datetime(cuts, 1, 1, Format="y");
end
else
% 날짜로 끊었을 때
dates = raceTable.Properties.VariableNames(2:end)';
timeStamp = datetime(dates);
end
names = string(raceTable.Username);
data = table2array(raceTable(:, 2:end));
T = array2timetable(data', 'RowTimes', timeStamp);
T.Properties.VariableNames = names;
%% GO!
barChartRace(T, NumDisplay=10, NumInterp=3, ...
Method="spline", ...
Position=[545 446 962 420], ...
XlabelName=sprintf("누적 채팅 건수 (%s~)", string(firstday)));
end'matlab' 카테고리의 다른 글
| pie 대신 piechart를 쓰자 (0) | 2025.09.26 |
|---|---|
| 매트랩에서의 클로저 (0) | 2025.09.19 |
| 단톡방 채팅 건수를 Bar Chart Race로 만들어보자. (0) | 2025.08.26 |
| (펌) MATLAB vs PYTHON (0) | 2025.07.08 |
| 코랩에서 매트랩 돌리기 (0) | 2025.06.29 |
댓글