在R中使用order(colSums())

3

我有一个 R 中的数据框矩阵,希望按列之和降序排序。我的数据范围从 +1 到 -1。我有一个代码可以完美地实现这个目标:

DF<-DF[, order(colSums(-DF))]

然而,我的一些数据中存在NA值(没有任何单个列或行是全部NA,因此我不能简单地删除整个列或行)。我认为数据没有被正确排序,因为包含NA的列没有被排序,只是放在已排序的列后面。

是否有一种方法可以按列总和对数据进行排序,同时也允许对包含NA的列进行排序?


是的,你可以查看 order(c(1,NA,3,NA)) 并且看到 NAs 确实被分配了最后的顺序。要修改它,也许可以使用 ?order 中提到的 na.last 选项。?colSums 显示它有一个 na.rm 选项,你可能想要使用它。顺便说一下,[dataframes] 不是 R 的正确标签。 - Frank
2个回答

6
如果我理解你的意思正确,你想把“NA列”排在“非NA列”后面,但是你还想根据colSums()函数应用于NA列中非NA单元格的结果来对NA列进行排序。你可以通过向order()添加一个额外的参数来实现这一点,并在其中使用na.rm=TRUE调用colSums()函数来打破连接。以下是一个演示,总共有4列,其中2列有NAs,2列没有:
set.seed(3L)
df <- setNames(rev(as.data.frame(replicate(4L,
     sample(c(seq(-1,1,0.5),NA),
            5L,rep=TRUE)))),letters[1:4])
df ## columns a and b are "NA columns", columns c and d are "non-NA columns"
##      a   b    c    d
## 1  1.0 0.5  0.5 -0.5
## 2 -1.0 0.5 -1.0  1.0
## 3  1.0 0.5 -0.5  0.0
## 4   NA 0.5  0.5 -0.5
## 5 -0.5  NA  0.5  0.5
colSums(-df) ## d should be moved before c, but can't tell yet about a and b
##    a    b    c    d
##   NA   NA  0.0 -0.5
colSums(-df,na.rm=TRUE) ## this can tiebreak a and b; b should be moved before a
##    a    b    c    d
## -0.5 -2.0  0.0 -0.5
df[,order(colSums(-df))] ## fails to order NA columns
##      d    c    a   b
## 1 -0.5  0.5  1.0 0.5
## 2  1.0 -1.0 -1.0 0.5
## 3  0.0 -0.5  1.0 0.5
## 4 -0.5  0.5   NA 0.5
## 5  0.5  0.5 -0.5  NA
df[,order(colSums(-df),colSums(-df,na.rm=TRUE))] ## tiebreaker orders NA columns properly
##      d    c   b    a
## 1 -0.5  0.5 0.5  1.0
## 2  1.0 -1.0 0.5 -1.0
## 3  0.0 -0.5 0.5  1.0
## 4 -0.5  0.5 0.5   NA
## 5  0.5  0.5  NA -0.5

抱歉,我误解了。看起来这就是您要找的内容:
df[,order(colSums(-df,na.rm=TRUE))]
##     b    a    d    c
## 1 0.5  1.0 -0.5  0.5
## 2 0.5 -1.0  1.0 -1.0
## 3 0.5  1.0  0.0 -0.5
## 4 0.5   NA -0.5  0.5
## 5  NA -0.5  0.5  0.5

请注意,传递na.rm=TRUE等同于将NA视为零,这与您的规定相反,即将NA视为零会破坏排序。

非常感谢您提供的详尽回复。实际上,我想将NA列与非NA列一样排序,之前所说的是NA列放在非NA列之后,但这不是我想要的!我认为只需在colSums函数中加入参数"na.rm=T"就可以实现我的需求了! - Ryan Rothman
抱歉,我刚意识到 NAs 为零不会影响我的排序结果 =) 干杯! - Ryan Rothman

1
为了让NA列与非NA列一起排序,使用"na.rm=TRUE"参数在"colSums"函数中。这将覆盖原始的colSums排序顺序,其中NA列在排序列后面未排序。最终代码如下:
DF<-DF[, order(colSums(-DF, na.rm=T))]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接