我在数据帧(这里称为“ a”)中有一列,其中序列的开头用1标记,而属于同一序列的后续事件用N / A标记。现在,我想创建一个新列(b)来索引属于同一序列(1:n)的所有事件,然后创建第三列(c)并用数字指示哪些事件属于同一序列。
我确信该解决方案非常简单并且引人注目,但是目前,我只是自己想出一个最好的解决方案。据我所知,其他问题也没有涵盖我的问题。
通常我正在使用dplyr(我还需要对我的数据做一些group_by,实际上比我在这里概述的要复杂得多),因此,如果可能的话,我对dplyr解决方案将非常满意!
以以下代码开头的示例:
df <- data.frame("a"= c(1, NA, NA, NA, 1, NA, 1, 1, 1))
最终效果如何:
df_final <- data.frame("a"= c(1, NA, NA, NA, 1, NA, 1, 1, 1), "b"= c(1, 2, 3, 4, 1, 2, 1, 1, 1), "c" = c(1, 1, 1, 1, 2, 2, 3, 4, 5))
答案 0 :(得分:1)
编辑
由于问题现在已经改变,现在获得预期的输出变得更加简单
library(dplyr)
df %>%
group_by(c = cumsum(!is.na(a))) %>%
mutate(b = row_number())
# a c b
# <dbl> <int> <int>
#1 1 1 1
#2 NA 1 2
#3 NA 1 3
#4 NA 1 4
#5 1 2 1
#6 NA 2 2
#7 1 3 1
#8 1 4 1
#9 1 5 1
使用基数R为:
df$c <- cumsum(!is.na(df$a))
df$b <- with(df, ave(a, c, FUN = seq_along))
原始答案
不幸的是,创建b
和c
的分组是不同的。对于b
,我们group_by
依次输入非NA值并对其进行累加,然后为每个组生成一个row_number
。对于c
,我们将rle
用作非NA值,并rep
食用values
lengths
次。
library(dplyr)
df %>%
group_by(group = cumsum(!is.na(a))) %>%
mutate(b = row_number()) %>%
ungroup() %>%
select(-group) %>%
mutate(c = with(rle(!is.na(a)), rep(cumsum(values), lengths)))
# A tibble: 9 x 3
# a b c
# <dbl> <int> <int>
#1 1 1 1
#2 NA 2 1
#3 NA 3 1
#4 NA 4 1
#5 1 1 2
#6 NA 2 2
#7 1 1 3
#8 1 1 3
#9 1 1 3
当然,这不是dplyr
特定的答案,也可以用基数R来回答
df$b <- with(df, ave(a, cumsum(!is.na(a)), FUN = seq_along))
df$c <- with(df, with(rle(!is.na(a)), rep(cumsum(values), lengths)))