R语言-数据框按数字排序

更新:

2016-08-25 解决TASSEL不能识别的BUG

R语言-数据框按数字排序常规方法排序将x2转换为数值型排序查看类型将因子转变为字符型再转变为数值型解决方案(有无法导入TASSEL)解决方案(可以导入TASSEL)

假设具有这样一组数据,想要根据x2的内容按照自然数顺序排序。

x1x2
111
2210
33100
44<NA>
552
66b
77t
88<NA>

常规方法排序

 
xxxxxxxxxx
x <- data.frame(x1=1:8,x2=c(1,10,100,NA,2,"t","b",NA))   # 新建数据框
x[order(x$x2),]   # 通常的排序手段

【结果】


x1 x2 1 1 1 2 2 10 3 3 100 5 5 2 7 7 b 6 6 t 4 4 <NA> 8 8 <NA>


可以看到,排序的规则是:1开头的→2开头的→字母→NA。并没有按照我们想要的按照数字的大小来排列。这是因为x2列中除了数字和缺失值还有字母(或字符串),只要含有字符串,R就会统一将数字转换为字符串,排序也变成了按照字符串排列。

将x2转换为数值型排序

 
xxxxxxxxxx
x[order(as.numeric(x$x2)),]   # 尝试将x2转换为数值型

【结果】


x1 x2 1 1 1 2 2 10 3 3 100 5 5 2 7 7 b 6 6 t 4 4 <NA> 8 8 <NA>


结果没有任何变化,为分析原因,查看一下x2类型。

查看类型

 
xxxxxxxxxx
class(x$x2)   # 查看x2的类型

【结果】


[1] "factor"


因子直接转变为数值型,会将第一个因子转变为1(本例中是1),第二个因子转变为2(本例中是10),单独是一类,以此类推...

既然不能直接将因子转变为数值型,那就做一个中间过度。

将因子转变为字符型再转变为数值型

 
xxxxxxxxxx
as.numeric(as.character(x$x2))   # 先转变为为字符型,再转变为数值型

【结果】


[1] 1 10 100 NA 2 NA NA NA


可以看出,字母由于不能直接转换成数字而变成了NA,但这似乎并不影响排序。

数据框按某列内容进行数字排序

 
xxxxxxxxxx
x[order(as.numeric(as.character(x$x2))),]   # 按数字排序尝试

【结果】


x1 x2 1 1 1 5 5 2 2 2 10 3 3 100 4 4 <NA> 6 6 t 7 7 b 8 8 <NA> Warning message: In order(as.numeric(as.character(x$x2))) : NAs introduced by coercion


有错误提示,但是仍然排好了。从结果中不难看出,只排了数字,而字符型和NA并没有按照顺序排列。因此,需要先对数据进行常规排列,再按照数值排列。

解决方案(有无法导入TASSEL)

 
xxxxxxxxxx
x <- data.frame(x1=1:8,x2=c(1,10,100,NA,2,"t","b",NA))   # 新建数据框
temp <- x[order(x$x2),]   # 排列非数字内容
sortResult <- temp[order(as.numeric(as.character(temp$x2))),]   # 排列数字内容,会报错,但可以工作
write.csv(sortResult,file.choose(),row.names=F)   # 将结果保存为文件
rm(x,temp,sortResult)   # 移除变量

【结果】


x1 x2 1 1 1 5 5 2 2 2 10 3 3 100 7 7 b 6 6 t 4 4 <NA> 8 8 <NA>


解决方案(可以导入TASSEL)

 
xxxxxxxxxx
x <- data.frame(x1=1:8,x2=c(1,10,100,NA,2,"t","b",NA))   # 新建数据框
### 解决NA排在最后无法导入TESSEL的BUG
x <- as.matrix(x)   # 将数据框转化为矩阵
v <- which(is.na(x))   # 获得所有NA的编号
x[v] <- "NA"   # 将NA转化为"NA"
x <- as.data.frame(x)   # 重新转化为矩阵
### END ###
temp <- x[order(x$x2),]   # 排列非数字内容
sortResult <- temp[order(as.numeric(as.character(temp$x2))),]   # 排列数字内容,会报错,但可以工作
write.csv(sortResult,file.choose(),row.names=F)   # 将结果保存为文件
rm(x,temp,sortResult)   # 移除变量

【结果】

x1 x2 1 1 1 5 5 2 2 2 10 3 3 100 7 7 b 4 4 NA 8 8 NA 6 6 t