如何在数据框中向左移动具有值的单元格

时间:2014-10-30 11:19:11

标签: r dataframe

我正在处理基本上与此类似的数据框架。


   X1   X2   X3 X4
x1  a    b   NA  c
x2  d   NA   NA  e
x3  f    g    h  i
x4  j   NA    k  l

我想要做的是将每个具有值的单元格向左移动。最后,所有具有值的单元格应该向左聚集,而所有具有NA的单元格应该向右聚集。

最后,数据框应如下所示:


   X1   X2   X3 X4
x1  a    b   c  NA
x2  d    e   NA NA
x3  f    g    h  i
x4  j    k    l NA

不幸的是,我不知道该怎么做。

非常感谢你的帮助。 (也许你也可以解释你的代码在做什么?)

拉​​米

5 个答案:

答案 0 :(得分:5)

还可以尝试使用length<-

df[] <- t(apply(df, 1, function(x) `length<-`(na.omit(x), length(x))))
df
#    X1 X2   X3   X4
# x1  a  b    c <NA>
# x2  d  e <NA> <NA>
# x3  f  g    h    i
# x4  j  k    l <NA>

答案 1 :(得分:5)

您可以从我的naLast function抓取"SOfun" package

结果将是matrix,但如果您愿意,可以轻松地将其打包在as.data.frame中:

as.data.frame(naLast(mydf, by = "row"))
#    X1 X2   X3   X4
# x1  a  b    c <NA>
# x2  d  e <NA> <NA>
# x3  f  g    h    i
# x4  j  k    l <NA>

使用以下命令安装软件包:

library(devtools)
install_github("mrdwab/SOfun")

答案 2 :(得分:4)

yourdata[]<-t(apply(yourdata,1,function(x){
                           c(x[!is.na(x)],x[is.na(x)])}))

应该有效:对于每一行,它用一个向量替换该行,该向量首先包含非NA的值,然后是NA值。

答案 3 :(得分:2)

如果你不介意循环:

ddf
   X1   X2   X3 X4
x1  a    b <NA>  c
x2  d <NA> <NA>  e
x3  f    g    h  i
x4  j <NA>    k  l

nddf = ddf
for(i in 1:nrow(ddf))
 nddf[i,] = sort(ddf[i,], na.last=T)

nddf
   X1 X2   X3   X4
x1  a  b    c <NA>
x2  d  e <NA> <NA>
x3  f  g    h    i
x4  j  k    l <NA>

如果您不想排序:

rowfn = function(rr){
 rr2 = rr; j=1
 for(i in 1:length(rr))    if(!is.na(rr[i])){ rr2[j] = rr[i] ;  j = j+1 } 
 if(j<(length(rr)+1)) for(k in j:length(rr))   rr2[k] = NA
 rr2
 }

ddf
   X1   X2   X3 X4
x1  a    b <NA>  c
x2  d <NA> <NA>  e
x3  f    g    h  i
x4  j <NA>    k  l

nddf = ddf
for(i in 1:nrow(ddf)) nddf[i,] = rowfn(ddf[i,])

nddf
   X1 X2   X3   X4
x1  a  b    c <NA>
x2  d  e <NA> <NA>
x3  f  g    h    i
x4  j  k    l <NA>

答案 4 :(得分:2)

你可以不用在R中循环来做到这一点。假设你有一个矩阵m,在这种情况下可能比data.frame更合适。然后,我们只使用order在行内排序,以便NA值最后。由于R中的排序是保守的,因此保留了非NA值的顺序。

v <- m[order(row(m), is.na(m))]
dim(v) <- dim(m)
t(v)
##     [,1] [,2] [,3] [,4]
## [1,] "a"  "b"  "c"  NA  
## [2,] "d"  "e"  NA   NA  
## [3,] "f"  "g"  "h"  "i" 
## [4,] "j"  "k"  "l"  NA  

要实现数百万行的性能,您可能希望使用基数排序。不幸的是,目前有限(为什么?)到100,000个唯一值,但它看起来像:

v2 <- m[sort.list(is.na(m) + (row(m)-1L)*2L + 1L, method="radix")]