【发布时间】:2018-01-31 12:05:45
【问题描述】:
考虑一个有序数据框,其列由值和 NA 组成,如下所示:
df <- data.frame(id=rep(1:6), value=c(NA,NA,23,45,12,76))
我想将 NA 的位置转移到数据框的前两行,同时保持值的顺序如下:
df$new_value <- c(23,45,12,76,NA,NA)
无论如何我可以做到这一点吗?谢谢!
【问题讨论】:
考虑一个有序数据框,其列由值和 NA 组成,如下所示:
df <- data.frame(id=rep(1:6), value=c(NA,NA,23,45,12,76))
我想将 NA 的位置转移到数据框的前两行,同时保持值的顺序如下:
df$new_value <- c(23,45,12,76,NA,NA)
无论如何我可以做到这一点吗?谢谢!
【问题讨论】:
我们可以在NA 元素上使用order
df$new_value <- df$value[order(is.na(df$value))]
df$new_value
#[1] 23 45 12 76 NA NA
通过is.na,它返回一个逻辑向量
is.na(df$value)
#[1] TRUE TRUE FALSE FALSE FALSE FALSE
在其上应用order 会返回
order(is.na(df$value))
#[1] 3 4 5 6 1 2
因为FALSE 按字母顺序排列在TRUE 之前。 order 值是向量的初始位置索引。这可以更容易理解
sort(c(TRUE, FALSE, TRUE), index.return = TRUE)
#$x
#[1] FALSE TRUE TRUE
#$ix
#[1] 2 1 3
【讨论】:
另一个仅当您的 NA 位于数据帧的最末端才有效的想法是使用 dplyr 中的 lead 函数来将您的数据 n 位置向前移动。所以对于你的情况,它会是,
dplyr::lead(df$value, sum(is.na(df$value)))
#[1] 23 45 12 76 NA NA
【讨论】:
group_by,例如:df <- data.frame(fact=c(1,1,1,2,2,2), id=rep(1:6), value=c(NA,44,23,NA,NA,76)) df <- df %>% group_by(fact) %>% mutate(newvar = dplyr::lead(df$value, sum(is.na(df$value))))
如果不聪明,也可以应用一些基本技术:
df$new_value <- c(df[!is.na(df$value), "value"], df[is.na(df$value), "value"])
id value new_value
1 1 NA 23
2 2 NA 45
3 3 23 12
4 4 45 76
5 5 12 NA
6 6 76 NA
【讨论】: