R 将NAs移动到数据帧中每列的末尾
我有这样一个数据框:R 将NAs移动到数据帧中每列的末尾,r,dataframe,sorting,na,R,Dataframe,Sorting,Na,我有这样一个数据框: df <- structure(list(a = c(NA, NA, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), b = c(NA, NA, NA, 1L, 2L, 3L, 4L, 5L, 6L, 7L), d = c(NA, NA, NA, NA, 1L, 2L, 3L, 4L, 5L, 6L)), .Names = c("a", "b", "d"), row.names = c(NA
df <- structure(list(a = c(NA, NA, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), b = c(NA, NA, NA, 1L, 2L, 3L, 4L, 5L, 6L, 7L), d = c(NA, NA, NA, NA, 1L, 2L, 3L, 4L, 5L, 6L)), .Names = c("a", "b", "d"), row.names = c(NA, -10L), class = "data.frame")
> df
a b d
1 NA NA NA
2 NA NA NA
3 1 NA NA
4 2 1 NA
5 3 2 1
6 4 3 2
7 5 4 3
8 6 5 4
9 7 6 5
10 8 7 6
更新以使我的问题更清晰。
df <- structure(list(a = c(NA, NA, 1, 5, 34, 7, 3, 5, 8, 4), b = c(NA,
NA, NA, 57, 2, 7, 9, 5, 12, 100), d = c(NA, NA, NA, NA, 5, 7,
2, 8, 2, 5)), .Names = c("a", "b", "d"), row.names = c(NA, -10L
), class = "data.frame")
> df
a b d
1 NA NA NA
2 NA NA NA
3 1 NA NA
4 5 57 NA
5 34 2 5
6 7 7 7
7 3 9 2
8 5 5 8
9 8 12 2
10 4 100 5
这似乎是一项容易的任务,但我仍不知道从哪里开始。。你能帮忙吗?在完全误解了这个问题之后,这里是我的最终答案:
# named after beetroot for being the first to ever need this functionality
beetroot <- function(x) {
# count NA
num.na <- sum(is.na(x))
# remove NA
x <- x[!is.na(x)]
# glue the number of NAs at the end
x <- c(x, rep(NA, num.na))
return(x)
}
# apply beetroot over each column in the dataframe
as.data.frame(lapply(df, beetroot))
#以beetroot命名,因为他是第一个需要此功能的人
beetroot使用Lappy
的另一种解决方案(无需对数据进行排序/重新排序-根据您的评论)
一些基准测试显示,基本解决方案是迄今为止最快的:
library("microbenchmark")
david <- function() lapply(df, function(x) c(x[!is.na(x)], x[is.na(x)]))
dt <- setDT(df)
david.dt <- function() dt[, names(dt) := lapply(.SD, function(x) c(x[!is.na(x)], x[is.na(x)]))]
microbenchmark(as.data.frame(lapply(df, beetroot)), david(), david.dt())
# Unit: microseconds
# expr min lq median uq max neval
# as.data.frame(lapply(df, beetroot)) 1145.224 1215.253 1274.417 1334.7870 4028.507 100
# david() 116.515 127.382 140.965 149.7185 308.493 100
# david.dt() 3087.335 3247.920 3330.627 3415.1460 6464.447 100
库(“微基准”)
david如果列数较少,我建议:
data.frame( a=sort(example$a, na.last=T), b=sort(example$b, na.last=T), d=sort(example$d, na.last=T))
最好的,
为了好玩,你也可以利用长度注意,这里的数据实际上发生了变化(从行的角度来看):这是故意的,还是你只是想把NA排序到底?这是故意的,我基本上希望所有的数字都按行对齐,因此,每一列都应该单独上移。无法想象你需要它做什么,但我发布了一个答案。您可能需要寻找data.table解决方案,它们通常是最快的。请稍候。。。你是说,如果你有一个简单的向量,像c(NA,2,3,1)
,那么结果必须是c(2,3,1,NA)
?这将真正改变这个问题@PascalvKooten是的,没错,对不起,如果不清楚,我会更新问题!在上一个示例中,您不需要像.matrix那样执行<代码>应用
自动强制矩阵。但是你应该将它包装成.data.frame,以将其返回到data.frame。谢谢,但正如Thomas的回答一样,这会对每列中的值进行排序,但我需要每列中的行顺序保持不变(NAs的位置应该是唯一会改变的东西)太棒了,就是这样!我感到很荣幸:D如果商业软件公司能够生成像样的csv输出文件,我也不需要它;)恭喜你找到了OP想要的东西,我喜欢。对于类似的过程,我唯一的其他想法是:lappy(df,function(x)x[order(is.na(x)))
这可能在计时方面效率较低。谢谢你的回答-抱歉,同时有这么多的答案/评论,所以我完全错过了你的答案/评论,只是刚才才看到!我已根据您的新数据集更新了结果。解决办法仍然存在unchanged@DavidArenburg我希望你不介意,但我在你的答案中添加了一些基准。
df[] <- lapply(df, function(x) c(x[!is.na(x)], x[is.na(x)]))
df
# a b d
# 1 1 57 5
# 2 5 2 7
# 3 34 7 2
# 4 7 9 8
# 5 3 5 2
# 6 5 12 5
# 7 8 100 NA
# 8 4 NA NA
# 9 NA NA NA
# 10 NA NA NA
library(data.table)
setDT(df)[, names(df) := lapply(.SD, function(x) c(x[!is.na(x)], x[is.na(x)]))]
df
# a b d
# 1: 1 57 5
# 2: 5 2 7
# 3: 34 7 2
# 4: 7 9 8
# 5: 3 5 2
# 6: 5 12 5
# 7: 8 100 NA
# 8: 4 NA NA
# 9: NA NA NA
# 10: NA NA NA
library("microbenchmark")
david <- function() lapply(df, function(x) c(x[!is.na(x)], x[is.na(x)]))
dt <- setDT(df)
david.dt <- function() dt[, names(dt) := lapply(.SD, function(x) c(x[!is.na(x)], x[is.na(x)]))]
microbenchmark(as.data.frame(lapply(df, beetroot)), david(), david.dt())
# Unit: microseconds
# expr min lq median uq max neval
# as.data.frame(lapply(df, beetroot)) 1145.224 1215.253 1274.417 1334.7870 4028.507 100
# david() 116.515 127.382 140.965 149.7185 308.493 100
# david.dt() 3087.335 3247.920 3330.627 3415.1460 6464.447 100
data.frame( a=sort(example$a, na.last=T), b=sort(example$b, na.last=T), d=sort(example$d, na.last=T))
x <- c(NA, 1, 2, 3)
x
# [1] NA 1 2 3
`length<-`(na.omit(x), length(x))
# [1] 1 2 3 NA
df[] <- lapply(df, function(x) `length<-`(na.omit(x), nrow(df)))
df
# a b d
# 1 1 57 5
# 2 5 2 7
# 3 34 7 2
# 4 7 9 8
# 5 3 5 2
# 6 5 12 5
# 7 8 100 NA
# 8 4 NA NA
# 9 NA NA NA
# 10 NA NA NA