dplyr中的条件求和(例如“引用另一行中刚刚更新的值”,例如在Excel中)

7秒

这个问题看起来很简单,应该有一个简单的解决方案,但是我找不到任何解决方案; /

我有一长串按时间索引的记录。时间间隔不是固定的。有一个类别变量,我感兴趣的是计算每种类别的条纹(连续多少天我们有“ A”,而不是例如“ B”。然后“ A”可能返回并开始另一种条纹)。在Excel中执行此操作仅需要参考上一行的if函数。在RI中,可以使用for循环来做到这一点,我在下面的玩具示例中提供了该循环。我主要想知道,如何在dplyr中完成它。

library(tidyverse)
library(lubridate)

set.seed(33)

# I create a date column - 20 dates starting from "2020-01-31", then uneven intervals, from 1 to 5 weeks
date <- rep(ymd(20200131), 20)

# (btw, this, I belive, should also be possible to do without a for loop, and I also cannot come up with a solution, 
# how):
for (i in 2:length(date)){
  date[i] <- date[i-1]+7*sample(1:5, 1)
}

# A categorical column
user <- c(rep("A",3), "B", rep("C",4), rep("B",5), rep("A", 6), "B")

df <- data.frame(date, user)

df$desired_result <-0

for (i in 2:nrow(df)){
  if (df[i, "user"] != df[i-1, "user"]) df[i, "desired_result"] <- 0
  else df[i, "desired_result"] <- as.integer(df[i, "date"] - df[i-1, "date"]) + df[i-1, "desired_result"] 
}

         date user desired_result
1  2020-01-31    A              0
2  2020-03-06    A             35
3  2020-04-03    A             63
4  2020-04-10    B              0
5  2020-04-17    C              0
6  2020-05-08    C             21
7  2020-05-29    C             42
8  2020-06-26    C             70
9  2020-07-03    B              0
10 2020-07-10    B              7
11 2020-07-24    B             21
12 2020-08-28    B             56
13 2020-09-18    B             77
14 2020-10-02    A              0
15 2020-10-09    A              7
16 2020-10-23    A             21
17 2020-11-06    A             35
18 2020-11-13    A             42
19 2020-11-20    A             49
20 2020-12-04    B              0

现在的问题是:如何在dplyr中执行此操作?

# This is wrong: "object 'result' not found":

df %>%  
  as_tibble() %>% 
  mutate(result = if_else(user == lag(user),
                          as.integer(date - lag(date)) + lag(result),
                          0))

# This is wrong: if condition is fulfilled, it adds as.integer(date - lag(date)) to 0, not to the result in the row above. 
# It dosen't proceed like a loop does, from the top of the column to the bottom, doesn't "update" values in the column, 
# as it proceeds.

df %>%  
  as_tibble() %>% 
  mutate(result = 0) %>% 
  mutate(result = if_else(user == lag(user),
                          as.integer(date - lag(date)) + lag(result),
                          0))

# A tibble: 20 x 4
   date       user  desired_result result
   <date>     <fct>          <dbl>  <dbl>
 1 2020-01-31 A                  0     NA
 2 2020-02-14 A                 14     14
 3 2020-03-13 A                 42     28
 4 2020-03-20 B                  0      0
 5 2020-04-03 C                  0      0
 6 2020-05-01 C                 28     28
 7 2020-05-08 C                 35      7
 8 2020-06-12 C                 70     35
 9 2020-07-17 B                  0      0
10 2020-08-21 B                 35     35
11 2020-09-04 B                 49     14
12 2020-09-18 B                 63     14
13 2020-10-16 B                 91     28
14 2020-10-23 A                  0      0
15 2020-11-13 A                 21     21
16 2020-11-27 A                 35     14
17 2020-12-25 A                 63     28
18 2021-01-08 A                 77     14
19 2021-02-12 A                112     35
20 2021-03-05 B                  0      0

我尝试了group_by(),但不适用,因为类别可能会返回并开始新的条纹cumsum(),到目前为止,它也没有帮助我。我强烈认为必须有一个基本的解决方案:)

阿克伦

我们可以rleid对“用户”进行分组操作,然后获得“日期”和lag“日期”之间的差,并获得累计和(cumsum

library(dplyr)
library(data.table)
df %>%
   group_by(grp = rleid(user)) %>% 
   mutate(desired_result2 = cumsum(as.integer(date - lag(date, 
           default = first(date))))) %>%
   ungroup %>%
   select(-grp)

-输出

# A tibble: 20 x 4
#   date       user  desired_result desired_result2
#   <date>     <chr>          <dbl>           <int>
# 1 2020-01-31 A                  0               0
# 2 2020-02-14 A                 14              14
# 3 2020-03-13 A                 42              42
# 4 2020-03-20 B                  0               0
# 5 2020-04-03 C                  0               0
# 6 2020-05-01 C                 28              28
# 7 2020-05-08 C                 35              35
# 8 2020-06-12 C                 70              70
# 9 2020-07-17 B                  0               0
#10 2020-08-21 B                 35              35
#11 2020-09-04 B                 49              49
#12 2020-09-18 B                 63              63
#13 2020-10-16 B                 91              91
#14 2020-10-23 A                  0               0
#15 2020-11-13 A                 21              21
#16 2020-11-27 A                 35              35
#17 2020-12-25 A                 63              63
#18 2021-01-08 A                 77              77
#19 2021-02-12 A                112             112
#20 2021-03-05 B                  0               0

注意:这里desired_result是来自OP的输出for循环,desired_result2是非环路输出


或者,这是可以做到rlebase R

df$desired_result2 <- with(df, ave(as.numeric(date), with(rle(user), 
   rep(seq_along(values), lengths)), FUN = function(x) 
      cumsum(c(0, diff(x)))))
df$desired_result2
#[1]   0  14  42   0   0  28  35  70   0  35  49
#[11]  63  91   0  21  35  63  77 112   0

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

CloudKit:在一个查询中获取记录和引用(例如在Parse中)

来自分类Dev

如何定期更新Ember模型(例如在setInterval中)?

来自分类Dev

使用VBA引用Excel中的另一行

来自分类Dev

通过检查另一行pyspark的条件来更新特定行中的值

来自分类Dev

将一行中的列值求和并保存到另一列中

来自分类Dev

将一行中的列值求和并保存到另一列中

来自分类Dev

从条件中减去另一行

来自分类Dev

在Xamarin Studio中使用ActiveX(例如在Visual Studio中添加引用)

来自分类Dev

在第一行中获取条件求和

来自分类Dev

更改C中stdin的颜色(例如在鱼壳中)

来自分类Dev

Excel公式:基于另一行中的对应值来计算一行中的唯一值

来自分类Dev

dplyr中的条件求和

来自分类Dev

Excel根据同一行中不同列的值求和

来自分类Dev

反应警告:在现有状态转换期间(例如在`render`中)无法更新

来自分类Dev

根据另一行中的值更新行中的值

来自分类Dev

如何从同一行中求和/减去时间值

来自分类Dev

Perl:如何使用 PERL 对一行中的值求和

来自分类Dev

根据Pyspark中另一列的值,有条件地从同一列的另一行值替换一行中的值?

来自分类Dev

AWS(例如在Azure中)是否可以替代WebJobs?

来自分类Dev

SystemJS从目录中导入“基本脚本”,例如在Python中

来自分类Dev

OpenCV:对矩阵的数学运算,例如在Matlab中

来自分类Dev

使用anaconda环境而不激活?(例如在Crontab中)

来自分类Dev

LibGdx拉伸/变形的像素(例如在像素艺术中)

来自分类Dev

是否可以设置边框以进行叠加(例如在photoshop中)

来自分类Dev

使用抽屉和标签导航,例如在Newstand中

来自分类Dev

LibGdx拉伸/变形的像素(例如在像素艺术中)

来自分类Dev

有限的个人资料,例如在Facebook中

来自分类Dev

如何制作新的标签,例如在Eclipse中查找错误

来自分类Dev

浏览图像(例如在图库中)(通过滑动图像)

Related 相关文章

  1. 1

    CloudKit:在一个查询中获取记录和引用(例如在Parse中)

  2. 2

    如何定期更新Ember模型(例如在setInterval中)?

  3. 3

    使用VBA引用Excel中的另一行

  4. 4

    通过检查另一行pyspark的条件来更新特定行中的值

  5. 5

    将一行中的列值求和并保存到另一列中

  6. 6

    将一行中的列值求和并保存到另一列中

  7. 7

    从条件中减去另一行

  8. 8

    在Xamarin Studio中使用ActiveX(例如在Visual Studio中添加引用)

  9. 9

    在第一行中获取条件求和

  10. 10

    更改C中stdin的颜色(例如在鱼壳中)

  11. 11

    Excel公式:基于另一行中的对应值来计算一行中的唯一值

  12. 12

    dplyr中的条件求和

  13. 13

    Excel根据同一行中不同列的值求和

  14. 14

    反应警告:在现有状态转换期间(例如在`render`中)无法更新

  15. 15

    根据另一行中的值更新行中的值

  16. 16

    如何从同一行中求和/减去时间值

  17. 17

    Perl:如何使用 PERL 对一行中的值求和

  18. 18

    根据Pyspark中另一列的值,有条件地从同一列的另一行值替换一行中的值?

  19. 19

    AWS(例如在Azure中)是否可以替代WebJobs?

  20. 20

    SystemJS从目录中导入“基本脚本”,例如在Python中

  21. 21

    OpenCV:对矩阵的数学运算,例如在Matlab中

  22. 22

    使用anaconda环境而不激活?(例如在Crontab中)

  23. 23

    LibGdx拉伸/变形的像素(例如在像素艺术中)

  24. 24

    是否可以设置边框以进行叠加(例如在photoshop中)

  25. 25

    使用抽屉和标签导航,例如在Newstand中

  26. 26

    LibGdx拉伸/变形的像素(例如在像素艺术中)

  27. 27

    有限的个人资料,例如在Facebook中

  28. 28

    如何制作新的标签,例如在Eclipse中查找错误

  29. 29

    浏览图像(例如在图库中)(通过滑动图像)

热门标签

归档