关于第一列按染色体排序,第二列按照数值升序排序

文章讲述了在使用Linux的sort命令进行文件排序时,特别是处理包含染色体信息和数值的列时,如何正确使用-k参数进行定制排序。强调了-k1,1V-k2,2n的用法,指出不设置-end可能导致的问题,并提醒读者注意不同版本sort命令的差异和更新带来的新功能。作者提倡深入理解常用命令的细节和版本变化。

关于第一列按染色体排序,第二列按照数值升序排序我踩的坑,
真的是对自己十分的无语啊,比如如下文件
在这里插入图片描述
正解方法为👇

sort -k1,1V -k2,2n input.txt > output.txt 

-k1,1 对第一列的第一个字符到最后一个字符进行排序[其实就是对第一列进行排序,但这个理解很重要]
-V, --version-sort natural sort of (version) numbers within text
十分的强大和好用,意思是给文本中的数字进行排序,有些以前的sort版本可能没有这个参数,建议升级。因为这个参数用上,再也不用担心因为文本中有数字而排序导致变成ASCII顺序,也不用需要特地编辑Chr1变成Chr01这类。

其中注意两点:
1
sort 参数 -k 的语法格式

F[.C][OPTS][,F[.C][OPTS]] 

上述和以前的sort语法结构是一个意思

 [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ] 

一定要注意区别 点"." 和 逗号 “,” 是各有用处的!
如1.3 代表从第一列的第三个字符开始排序
1,1 上面解释过了。来自其他博客的警告👇

“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

已经解释得很清楚了,但是我还是踩了坑,因为没有设置end,
比如这个,对上述图片的内容进行排序
第一列按染色体排序,第二列按照数值升序

sort -k 1 -k 2n file.txt > ceshi1.txt

看起来这个代码没有问题,但是因为 -k 1 没设end,导致出现“第一列能正常排序,第二列怎么不按数值排序,还是默认的排序方法呢??”的人生疑问。如果你用这个代码没有哦问题当我没说。。

2
对自己也是对他人的忠告
对一个linux常用的命令还是得多注意细节,得吃透,比如 sed awk grep sort cat cp cut less等等等等,而且得注意版本,更新一个版本,可能有了新的好用的参数,也可能使用命令和以前的有所差别。总之,在借助网上教程的便利前提下,也得时刻警醒自己,教程不是一成不变的,用的参数、版本都需要注意。

参考博文:
sort用法及-k选项
BED文件如何排序,sort按列排序

% 导入数据 data = readtable("D:\附件-男胎检测数据2.xlsx", 'VariableNamingRule', 'preserve'); % 保留关键列 coreFields = {'孕妇代码', '孕妇BMI', '检测孕周', 'Y染色体浓度', '检测抽血次数'}; data = data(:, coreFields); % 清洗缺失值 data = rmmissing(data, 'DataVariables', coreFields); % 确保“检测孕周”是字符串 data.('检测孕周') = string(data.('检测孕周')); % 转换检测孕周为连续型GA gaCell = arrayfun(@parseGA, data.('检测孕周'), 'UniformOutput', false); data.GA = cell2mat(gaCell); % 过滤GA不在[10,25]的样本 data = data(data.GA >= 10 & data.GA <= 25, :); % 重命名列为英文 data.Properties.VariableNames = {'pID', 'BMI', 'GA_str', 'Y_concentration', 'test_count', 'GA'}; % 按孕妇代码分组并按检测抽血次数排序 grp = findgroups(data.pID); groupedData = splitapply(@(x) {sortrows(x, 'test_count')}, data, grp); %% 2. 计算每个孕妇的最早达标时间T_early,p [pIDs, earlyT] = computeEarlyT(groupedData); %% 3. 有序聚类分组(按BMI) % 提取每个孕妇的BMI(组内一致,取第一个) bmi = zeros(length(groupedData), 1); for i = 1:length(groupedData) bmi(i) = groupedData{i}.BMI(1); end % 按BMI升序排序 [sortedBMI, sortIdx] = sort(bmi); sortedT = earlyT(sortIdx); % 肘部法则确定最优分组数(最大尝试5组) maxM = 5; bestM = elbowMethod(sortedBMI, sortedT, maxM); % 执行有序聚类 [groups, bmiBounds] = optimalPartition(sortedBMI, sortedT, bestM); %% 4. 计算每组最佳NIPT时点及风险 nGroups = bestM; bestGA = zeros(nGroups, 1); groupRisk = zeros(nGroups, 1); gaRange = [10, 25]; for i = 1:nGroups idx = find(groups == i); groupT = sortedT(idx); minT = min(groupT); % 组内最早达标时间 [bestGA(i), groupRisk(i)] = computeBestGA(groupT, minT, gaRange); end totalRisk = sum(groupRisk); % 总风险 %% 5. 检测误差影响分析(模拟σ=0.5%,1%,2%) sigmas = [0.5, 1, 2]; errResults = cell(length(sigmas), 4); for s = 1:length(sigmas) sigma = sigmas(s); [errT, errG, errGA, errR] = analyzeError(data, groupedData, sortedBMI, sortedT, bestM, sigma); errResults{s,1} = errT; errResults{s,2} = errG; errResults{s,3} = errGA; errResults{s,4} = errR; end %% 输出结果 disp('===== BMI分组区间 ====='); for i = 1:nGroups if i == nGroups fprintf('组%d: [%.2f, %.2f]\n', i, bmiBounds(i), bmiBounds(i+1)); else fprintf('组%d: [%.2f, %.2f)\n', i, bmiBounds(i), bmiBounds(i+1)); end end disp(' '); disp('===== 每组最佳NIPT时点(周) ====='); for i = 1:nGroups fprintf('组%d: %.4极f\n', i, bestGA(i)); end disp(' '); disp('===== 每组潜在风险值 ====='); for i = 1:nGroups fprintf('组%d: %.0f\n', i, groupRisk(i)); end fprintf('总风险值: %.0f\n', totalRisk); disp(' '); disp('===== 检测误差影响分析 ====='); for s = 1:length(sigmas) sigma = sigmas(s); errT = errResults{s,1}; errGA = errResults{s,3}; errR = errResults{s,4}; fprintf('\nσ=%.1f%%时:\n', sigma); fprintf('最早达标时间均值变化: %.4f → %.4f\n', ... mean(earlyT(~isinf(earlyT))), mean(errT(~isinf(errT)))); fprintf('最佳时点均值变化: %.4f → %.4f\n', ... mean(bestGA(~isnan(bestGA))), mean(errGA(~isnan(errGA)))); fprintf('总风险变化: %.0f → %.0f\n', totalRisk, errR); end data_clean = data_clean(valid_idx, :); 错误使用 splitapply (第 61 行) 组编号必须为正整数向量,并且不能为稀疏向量。 >> 根据报错提示,修改代码
09-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值