我正在处理基本上与此类似的数据框架。
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
不幸的是,我不知道该怎么做。
非常感谢你的帮助。 (也许你也可以解释你的代码在做什么?)
拉米
答案 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")]