如何解决R cumsum 与 if 条件
假设我有这个数据框
df <-
data.frame(
id = seq(1,8),type = c("NEW","OLD","NEW","OLD")
)
我想为每个 TYPE OLD 组创建“段”,因此结果是这样的 - 每个段都用订单号标记,请注意前两个旧类型的段为 1,第二段标记为2.
df <-
data.frame(
id = seq(1,"OLD"),segment = c(0,1,2,3)
)
但是我在 R 中实现这一点时遇到了问题。我可以为类型段创建 if else,我想我需要通过 cumsum 函数来完成,但我还没有找到方法。
mutate(
segment = if_else(type == "NEW",1)
)
解决方法
这是一种使用行数差异方法的方法。这种方法经常用于解决数据库中的间隙和孤岛问题,这基本上也是这个 R 问题。
df$segment <- ifelse(df$type == "OLD",df$id - cumsum(df$type == "OLD"),0)
df
id type y segment
1 1 NEW 1 0
2 2 OLD 1 1
3 3 OLD 1 1
4 4 NEW 2 0
5 5 OLD 2 2
6 6 OLD 2 2
7 7 NEW 3 0
8 8 OLD 3 3
这里的方法是取整个数据帧上的序列与仅包含 OLD
条目的序列之间的差异。考虑以下差异:
1 2 3 4 5 6 7 8
0 1 2 2 3 4 4 5
---------------
1 1 1 2 2 2 3 3
那么,我们只保留属于OLD
的上述差值。
另一种使用 cumsum
的方法:
df %>% mutate(
segment = cumsum(lag(type,1,'NEW') == 'NEW' & type == 'OLD') * (type == 'OLD'))
# id type segment_expected segment
# 1 1 NEW 0 0
# 2 2 OLD 1 1
# 3 3 OLD 1 1
# 4 4 NEW 0 0
# 5 5 OLD 2 2
# 6 6 OLD 2 2
# 7 7 NEW 0 0
# 8 8 OLD 3 3
此处使用的 df
是:
df <-data.frame(
id = seq(1,8),type = c("NEW","OLD","NEW","OLD"),segment_expected = c(0,2,3))
,
使用 rle
的基础 R -
transform(df,segment = with(rle(type == 'NEW'),rep(cumsum(values) * as.integer(!values),lengths)))
# id type segment
#1 1 NEW 0
#2 2 OLD 1
#3 3 OLD 1
#4 4 NEW 0
#5 5 OLD 2
#6 6 NEW 0
#7 7 NEW 0
#8 8 OLD 3
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。