【问题标题】:dcast with condition in r在 r 中有条件的 dcast
【发布时间】:2017-05-31 21:55:58
【问题描述】:
> log_df[1:10, ]
      tagid            happened status
1  03B2ACE7 2016-06-28 18:07:36   open
2  03B2ACE7 2016-06-28 18:36:15 closed
3  03B2ACE7 2016-06-29 07:29:59   open
4  03B2ACE7 2016-06-29 08:06:23 closed
5  03B2ACE7 2016-06-30 16:10:48   open
6  03B2ACE7 2016-06-30 17:23:55   open
7  03B2ACE7 2016-07-01 10:12:06 closed
8  03B2ACE7 2016-07-01 13:39:58 closed
9  03B2ACE7 2016-07-02 10:08:40   open
10 03B2ACE7 2016-07-02 13:33:01 closed
...

以上是我的数据。 我想制作的是:

      tagid                open               closed
1  03B2ACE7 2016-06-28 18:07:36  2016-06-28 18:36:15
2  03B2ACE7 2016-06-29 07:29:59  2016-06-29 08:06:23
3  03B2ACE7 2016-06-30 16:10:48  2016-07-01 10:12:06
...

我试图让它与 reshape2 包中的 dcast 一起工作。 但是,我必须有选择地选择我只接的地方

“打开”是第一个,只有在关闭之后出现的那些,以及在打开之前出现的“关闭”。

所以从 log_df 开始,第 6 行和第 7 行将被忽略..

我真的被困住了,不知道该怎么做。。 也许 dcast 不是最好的方法?

请帮忙!非常感谢!

【问题讨论】:

    标签: r reshape2 dcast


    【解决方案1】:

    使用dplyrtidyr(来自潮汐,reshape的进化):

    library(dplyr)
    library(tidyr)
    
    df %>% 
        filter((status == 'open' & lag(status, default = "") != 'open') | (status == 'closed' & lead(status, default = "") != "closed")) %>% 
        mutate(r = ceiling(row_number() / 2)) %>% 
        spread(status, happened)
    
    #>      tagid r              closed                open
    #> 1 03B2ACE7 1 2016-06-28 18:36:15 2016-06-28 18:07:36
    #> 2 03B2ACE7 2 2016-06-29 08:06:23 2016-06-29 07:29:59
    #> 3 03B2ACE7 3 2016-07-01 13:39:58 2016-06-30 16:10:48
    #> 4 03B2ACE7 4 2016-07-02 13:33:01 2016-07-02 10:08:40
    

    它:

    1. 根据特定条件过滤data.frame
    2. 添加一列来存储“组”
    3. 将值传播到列(相当于 dcast)

    数据:

    df <- read.table(text = '      tagid            happened status
    1  03B2ACE7 "2016-06-28 18:07:36"   open
    2  03B2ACE7 "2016-06-28 18:36:15" closed
    3  03B2ACE7 "2016-06-29 07:29:59"   open
    4  03B2ACE7 "2016-06-29 08:06:23" closed
    5  03B2ACE7 "2016-06-30 16:10:48"   open
    6  03B2ACE7 "2016-06-30 17:23:55"   open
    7  03B2ACE7 "2016-07-01 10:12:06" closed
    8  03B2ACE7 "2016-07-01 13:39:58" closed
    9  03B2ACE7 "2016-07-02 10:08:40"   open
    10 03B2ACE7 "2016-07-02 13:33:01" closed', h = T)
    

    【讨论】:

    • 为了保持第一次打开和最后一次关闭,从而从原始df中过滤掉第6行和第7行,您可以改为filter((status == 'open' &amp; lag(status,default="") != 'open') | (status == 'closed' &amp; lead(status,default="")!="closed"))
    • 上面的解决方案是一个很好的解决方案。如果连续有几个打开,它会在关闭之前保持最后一个打开,如果连续有几个关闭,它会在打开之前保持最后一个关闭,然后它会执行spread。如果,如您的示例(忽略第 6 行和第 7 行),您希望保留第一个打开和最后一个关闭,您可以将上述解决方案中的 filter 替换为另一个 filter
    • 对不起,我明白你的意思了,我没有注意过滤了哪个“后续事件”。使用@Lamia 的过滤器修复代码,这很好。
    猜你喜欢
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    相关资源
    最近更新 更多