如何用 NA 分隔包含 NA 的列?

How to separate a Column which contains NA´s by NA`s?

第一次提问,请多多包涵:)

我觉得很简单。我有一个 data.frame,它由一列 "Time" 组成。它看起来像这样:

-------------------------
> head(Times,10)
   Times
1     NA
2  0.448
3  0.130
4     NA
5     NA
6  0.462
7  0.427
8  0.946
9  0.227
10    NA
>
------------------------

想法是,第一个 NA 表示序列的开始,因此,后续时间应该来自同一标签。到达下一个 NA 条目后,序列完成。

我现在想创建一个新的 data.frame,它将 NA 之间的数字放入列中,并按行分隔序列。

  Time1 Time2 Time3 Time4
1 0.448 0.130 0.123 
2 0.462 0.427 0.946 0.227
>
---------------------------------

你能帮忙吗?

Times <- read.table(text = "Times
1     NA
2  0.448
3  0.130
4     NA
5     NA
6  0.462
7  0.427
8  0.946
9  0.227
10    NA", header = TRUE)

#identify values that belong together
Times$ind <- cumsum(is.na(Times$Times)) %/% 2 + 1

Times <- na.omit(Times) #remove NA values

#identify columns
Times$col <- unlist(tapply(Times$ind, factor(Times$ind), seq_along))

#reshape to wide format 
reshape(Times, timevar = "col", idvar = "ind", direction = "wide")
#  ind Times.1 Times.2 Times.3 Times.4
#2   1   0.448   0.130      NA      NA
#6   2   0.462   0.427   0.946   0.227

我使用 base R 只是为了好玩。如果你需要更高效的东西,你应该使用包 data.table.

这是使用 dplyrtidyr 的解决方案:

library(dplyr)
library(tidyr)
Times %>% filter(!(is.na(Times) & is.na(lead(Times)))) %>%
          mutate(series = cumsum(is.na(Times)))  %>%
          filter(!is.na(Times)) %>%
          group_by(series) %>%
          mutate(count = paste0("Times.", row_number())) %>%
          spread(count, Times)

Source: local data frame [2 x 5]

  series Times.1 Times.2 Times.3 Times.4
   (int)   (dbl)   (dbl)   (dbl)   (dbl)
1      1   0.448   0.130      NA      NA
2      2   0.462   0.427   0.946   0.227

使用data.table v1.9.6(使用来自@Roland 的回答的数据):

require(data.table) # v1.9.6+
setDT(Times)[, `:=`(grp = seq_len(.N), rle = rle), by = .(rle = rleid(is.na(Times)))]
dcast(na.omit(Times, by="Times"), rle ~ grp, value.var="Times")
#    rle     1     2     3     4
# 1:   2 0.448 0.130    NA    NA
# 2:   4 0.462 0.427 0.946 0.227

您可以使用 paste0("Times", rle) 获取问题中显示的列名称。