【问题标题】:split a data frame using after a date where the value of another variable reaches to max/min on that date在另一个变量的值在该日期达到最大值/最小值的日期之后使用拆分数据框
【发布时间】:2021-02-06 03:20:20
【问题描述】:

我有一个类似于以下的数据集:

df <- data.frame( 
                date = c("2020-02-01", "2020-02-02", "2020-02-03", "2020-02-04", "2020-02-05", "2020-02-06"),
               value = c(0,1,2,7,3,4))

我想将我的数据框拆分为两个较小的数据框,以便第一个数据框在值达到最大值(即 7)之前包含原始数据框的一部分,而数据框的第二部分包含原始数据框的其余部分如下:

df1 <- data.frame(
                 date = c("2020-02-01", "2020-02-02", "2020-02-03"),
                 value = c(0,1,2)
                 )
df2 <- data.frame(
                 date = c("2020-02-04", "2020-02-05", "2020-02-06"),
                 value = c(7, 3, 4)
                 )

*** 问题的第二部分 现在假设我有以下数据集,其中包括多个由 ID 标识的对象。所以,我想和上面解释的一样,应用于所有对象(ID)

df <- data.frame( ID = c(1,1,1,1,1,1,2,2,2,2),
                date = c("2020-02-01", "2020-02-02", "2020-02-03", "2020-02-04", "2020-02-05", "2020-02-06", "2020-02-01", "2020-02-02","2020-02-03", "2020-02-04"),
               value = c(0,1,2,7,3,4,10,16,11,12))

感谢您的宝贵时间。

【问题讨论】:

    标签: r dataframe datetime split


    【解决方案1】:

    您可以使用which.max 获取max 值的索引,并使用它来子集数据帧。

    ind <- which.max(df$value)
    df1 <- df[seq_len(ind - 1), ]
    df2 <- df[ind:nrow(df), ]
    
    df1
    # A tibble: 3 x 2
    #  date       value
    #  <chr>      <dbl>
    #1 2020-02-01     0
    #2 2020-02-02     1
    #3 2020-02-03     2
    
    df2
    # A tibble: 3 x 2
    #  date       value
    #  <chr>      <dbl>
    #1 2020-02-04     7
    #2 2020-02-05     3
    #3 2020-02-06     4
    

    如果有很多 ID,我们可以创建一个数据框列表,并且我们必须为每个 ID 执行此操作。

    result <- df %>%
                group_split(ID) %>%
                purrr::map(~{.x %>% 
                   group_split(row_number() < which.max(value), .keep = FALSE)})
    
    ## In case, someone is interested you could make a data frame from the list above as follows: 
    result_df <- result %>%
    bind_rows()
    
    
    

    【讨论】:

    • 谢谢。如果我想将其应用于更大的数据集,包括具有不同 ID 的对象,该怎么办?我的意思是一起使用巢和地图之类的东西。
    • @SeyedHosseini 请相应地更新您的示例并显示它的预期输出。还要确保您的示例实际运行。例如,使用as_tibble 会为我返回错误,我必须将其更改为tibble
    • 谢谢@ronak-shah,按照您的指示,我编辑了这个问题。感谢您的时间和建议。
    • 检查更新的答案。最好创建数据框列表。
    【解决方案2】:

    另一种使用基础 R 的方法:

    > df
            date value
    1 2020-02-01     0
    2 2020-02-02     1
    3 2020-02-03     2
    4 2020-02-04     7
    5 2020-02-05     3
    6 2020-02-06     4
    > df1 <-  df[1:(which(df$value == max(df$value)) - 1), ]
    > df2 <- df[which(df$value == max(df$value)):nrow(df), ]
    > df1
            date value
    1 2020-02-01     0
    2 2020-02-02     1
    3 2020-02-03     2
    > df2
            date value
    4 2020-02-04     7
    5 2020-02-05     3
    6 2020-02-06     4
    > 
    

    对于分组数据:

    > mylist <- df %>% split(f = df$ID)
    > mylist
    $`1`
      ID       date value
    1  1 2020-02-01     0
    2  1 2020-02-02     1
    3  1 2020-02-03     2
    4  1 2020-02-04     7
    5  1 2020-02-05     3
    6  1 2020-02-06     4
    
    $`2`
       ID       date value
    7   2 2020-02-01    10
    8   2 2020-02-02    16
    9   2 2020-02-03    11
    10  2 2020-02-04    12
    
    > split_list <- lapply(mylist, function(x) x[1:(which.max(x$value) - 1),])
    > split_list <- append(split_list, lapply(mylist, function(x) x[which.max(x$value): nrow(x),]))
    > split_list
    $`1`
      ID       date value
    1  1 2020-02-01     0
    2  1 2020-02-02     1
    3  1 2020-02-03     2
    
    $`2`
      ID       date value
    7  2 2020-02-01    10
    
    $`1`
      ID       date value
    4  1 2020-02-04     7
    5  1 2020-02-05     3
    6  1 2020-02-06     4
    
    $`2`
       ID       date value
    8   2 2020-02-02    16
    9   2 2020-02-03    11
    10  2 2020-02-04    12
    
    > 
    

    【讨论】:

    • 谢谢。如果我想将其应用于更大的数据集,包括具有不同 ID 的对象,该怎么办?我的意思是一起使用巢和地图之类的东西
    • 感谢您的回复。我更新了问题以澄清我的观点。感谢您的时间和建议。
    • 已添加分组数据的代码,请检查是否适合您。
    • 感谢您的宝贵时间,因为我不太擅长基本的 R,@ronak-shah 的回答对我来说效果更好。
    猜你喜欢
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2021-09-23
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2021-12-15
    相关资源
    最近更新 更多