数字数据框列不正确地作为字符串排序

gre*_*gar 9 r dataframe

我在数据框中有一些医院数据,从csv读入.我尝试按用户定义的列排序数据框col,然后按医院的名称排序,如下所示:

col <- 'Hospital.30.Day.Death..Mortality..Rates.from.Pneumonia'
hospitals.sorted <- hospitals[order(hospitals[,col], hospitals$Hospital.Name),]
Run Code Online (Sandbox Code Playgroud)

但我想我错过了一些东西; 它看起来col像字符串:

> hospitals.sorted
... # so far so good # ...
2749                                                   10.0
2831                                                   10.0
2891                                                   10.0
2837                                                   10.1
2824                                                   10.1
2774                                                   10.1
... # not so good # ...
2856                                                   15.7
2834                                                   15.9
2797                                                   16.0
2835                                                    7.4
2850                                                    7.7
2789                                                    8.1
... # there are some non-numeric values at the very bottom # ...
2806                                                    9.9
2867                                                    9.9
2884                                                    9.9
2808                                          Not Available
2913                                          Not Available
2911                                          Not Available
Run Code Online (Sandbox Code Playgroud)

只是为了确认该列实际上是数字的:

> sapply(hospitals, mode)
Hospital.30.Day.Death..Mortality..Rates.from.Pneumonia 
"numeric" 
Hospital.Name 
"numeric"
Run Code Online (Sandbox Code Playgroud)

我不知道为什么Hospital.Name数字显然不是.

其他我试图无济于事的事情:

  • as.numeric(hospitals[,col])在里面使用order
  • 在排序之前删除"不可用"值

我可能会遗漏一些基本的东西.HALP!

Rei*_*son 16

在数据框架中,各个组件必须是原子矢量.您在所提及的变量中包含数字和字符数据,因此R将读取它作为字符向量.但是,由于参数的默认设置stringsAsFactors,字符向量将被转换为因子.因此,它看起来像数字存储为数字.然而,那些只是标签,你被欺骗了.

同样,这个mode()电话也欺骗了你.考虑

> mode(factor(c(1:10, "a")))
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)

然而,这显然不是"数字"数据.接下来考虑

> mode(factor(letters))
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)

这掩盖了这样一个事实,即内部R的因子被存储为数字变量,这正是mode()告诉你的.mode()这项工作是错误的工具.

要测试变量是否为数字,请is.numeric()改用:

> is.numeric(factor(c(1:10, "a")))
[1] FALSE
> is.numeric(factor(letters))
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

至于解决方案.需要将"不可用"设置为NA.您可以通过添加na.strings = "Not Available"read.table()(或您使用的任何包装器)调用来读取数据时执行此操作.这应该足以理清字符>因子转换.

最重要的提示是始终查看str()应用于对象的输出,以检查R是否已根据需要读取数据.所以你应该这样做:

str(hospitals)
Run Code Online (Sandbox Code Playgroud)

并注意根据R的变量类型.

关于你尝试过的其他事情:

  1. as.numeric(hospitals[,col])将生成包含因子的每个元素的级别ID的数字向量.如果因子按特定顺序排序,那么它的级别表示也是如此.要将一个因子(它的标记版本)转换为数字,您需要一个中间步骤:as.numeric(as.character(hospitals[, col])).这不会解决你在这里遇到的实际问题,因为你在变量中有字符数据,而R将无法将其转换为数字.它将转换"Not Available"NA,如果你尝试过可能有效as.numeric(as.character(hospitals[, col])).
  2. 通过删除"Not Available",我假设通过删除那些行/元素?,仍将剩余的观察结果留在一个因子中.由于上述原因不适用,因为它会对标签/级别进行alpha排序.