R语言中基于ID向量与数据框全列排序数据框的问题
问题
需要基于一个ID向量和另一个数据框的所有列对数据框进行排序。手动指定列顺序的代码可正常运行:
admix.tmp = cbind(admix, id.namestest) if (K==3) { admix.sort.tmp = admix.tmp[order(id.namestest[,2], admix[,1],admix[,2],admix[,3]),]}
但尝试用列顺序向量sort.order = c(1,2,3)改写为以下代码时出现错误:
admix.sort.tmp = admix.tmp[order(id.namestest[,2], admix[,sort.order]),]
错误信息:
Error in order(id.namestest[, 2], admix[, c(1, 2, 3)]) : argument lengths differ
使用asplit(admix, 2)尝试也得到相同错误。
解决方法
order()函数要求传入多个独立的向量参数,而你直接传入admix[,sort.order]时,会把整个子数据框作为单个参数传递——数据框的“长度”是列数,而id.namestest[,2]是长度为行数的向量,两者长度不匹配,因此报错。
可以用do.call()将数据框的列拆分为单独参数传递给order(),实现和手动指定列相同的效果:
sort.order = c(1,2,3) admix.sort.tmp = admix.tmp[do.call(order, c(list(id.namestest[,2]), admix[,sort.order])), ]
代码解释
list(id.namestest[,2])把ID向量包装成列表元素,保证它作为order()的第一个参数admix[,sort.order]会被自动拆分为列表的后续元素(每一列对应一个列表项)do.call(order, ...)会把列表中的每个元素依次作为order()的独立参数,等价于手动写order(id.namestest[,2], admix[,1], admix[,2], admix[,3])
如果需要对admix的所有列排序,无需手动定义sort.order,直接用以下代码即可:
admix.sort.tmp = admix.tmp[do.call(order, c(list(id.namestest[,2]), admix)), ]
内容的提问来源于stack exchange,提问作者M. Beausoleil
相关产品推荐
相关产品推荐

