【问题标题】:Create new column when when values repeat 3 or more times当值重复 3 次或更多次时创建新列
【发布时间】:2019-09-14 00:04:41
【问题描述】:

问题

我正在尝试根据前一列 (a) 的值创建一个新列 (b)。 a 列是二进制的,由 0 的1 的 组成。如果a 列中连续有三个或更多1,则将它们保留在b 列中。我接近所需的输出,但是当连续有两个 1 时,ifelse 会获取第二个值,因为它满足第一个条件。

期望的输出——列b

df <- data.frame(a = c(1,1,1,0,0,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,1),
                 b = c(1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1))
df
   a b
1  1 1
2  1 1
3  1 1
4  0 0
5  0 0
6  1 0
7  0 0
8  1 0 #
9  1 0 # 
10 0 0
11 1 1
12 1 1
13 1 1
14 0 0
15 1 0 #
16 1 0 #
17 0 0
18 1 1
19 1 1
20 1 1
21 1 1

尝试失败...s

require(dplyr)
df_fail <- df %>% mutate(b=ifelse((lag(df$a) + df$a) > 1 |(df$a + lead(df$a) + lead(df$a,2)) >= 3, df$a,NA))

df_fail
   a b
1  1 1
2  1 1
3  1 1
4  0 0
5  0 0
6  1 0
7  0 0
8  1 0
9  1 1 # should be 0
10 0 0
11 1 1
12 1 1
13 1 1
14 0 0
15 1 0
16 1 1 # should be 0
17 0 0
18 1 1
19 1 1
20 1 1
21 1 1

【问题讨论】:

    标签: r if-statement dplyr


    【解决方案1】:

    我们可以使用rle from base R 将小于3个重复1的元素改为0

    inverse.rle(within.list(rle(df$a), values[values == 1 & lengths <3] <- 0))
    #[1] 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1
    

    或者从data.table使用rleid

    library(data.table)
    library(dplyr)
    df %>% 
       group_by(grp = rleid(a)) %>%
       mutate(b1 = if(n() <3 & all(a == 1)) 0 else a) %>%
       ungroup %>%
       select(-grp)
    

    【讨论】:

    • 我实际上只是将您的初始答案换成了我的ifelse,效果很好。 df_fail &lt;- df %&gt;% mutate(b=inverse.rle(within.list(rle(a), values[values == 1 &amp; lengths &lt;3] &lt;- 0)))
    • @NickDylla 在mutate 中不需要df$a,可以只是a
    • 不错,忘了dplyrize ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多