如何在R中使用上面的1行和后面的1行计算后续非零行的组?

时间:2018-02-18 03:57:35

标签: r

我想创建另一个仅列出事件的数据框(df)。例如,df(XX,YY)应该有4个事件。列XX应该是大于零的事件值的总和,由零行分隔。 YY列应为Max minus Min,事件值大于零,由零行分隔。

    XX   YY
1  3.0 23.6
2  0.0 23.2
3  0.0 23.7
4  0.0 25.2
5  1.3 24.5
6  4.8 24.2
7  0.2 23.1
8  0.0 23.3
9  0.0 23.9
10 0.0 24.3
11 1.8 24.6
12 3.2 23.7
13 0.0 23.2
14 0.0 23.6
15 0.0 24.1
16 0.2 24.5
17 4.8 24.1
18 3.7 22.1
19 0.0 23.4
20 0.0 23.8

从我的表中,我想得到如下结果。

事件1. XX [1] = sum(row1,row2); YY [1] = [Max(row1,row2) - Min(row1,row2)] XX [1] = 3,YY [1] = 0.4

事件2. XX [2] =总和(第4行,第5行,第6行,第7行,第8行); YY [2] = [Max(row4,row5,row6,row7,row8) - Min(row4,row5,row6,row7,row8)] XX [2] = 6.3,YY [2] = 2.1

事件3. XX [3] =总和(第10行,第11行,第12行,第13行); YY [3] = [Max(row10,row11,row12,row13) - Min(row10,row11,row12,row13)] XX [3] = 5,YY [3] = 1.4

事件4. XX [4] =总和(第15行,第16行,第17行,第18行,第19行); YY [4] = [Max(row15,row16,row17,row18,row19) - Min(row15,row16,row17,row18,row19)] XX [4] = 5,YY [4] = 2.4

   XX    YY
1  3    0.4
2  6.3  2.1
3  5    1.4
4  8.7  2.4

1 个答案:

答案 0 :(得分:2)

基础R中的方法1

  1. 将原始data.frame拆分为list

    lst <- split(df, c(rep(1, 2), 2, rep(3, 5), 4, rep(5, 4), 6, rep(7, 5), 8));
    lst <- lst[sapply(lst, function(x) nrow(x) > 1)];
    names(lst) <- NULL;
    

    请注意,这与原始数据完全相同,唯一的区别是相关行被分组到单独的data.frame中,并且已删除不相关的行(row3,row9,row14,row20)。 / p>

  2. 接下来定义自定义函数

    # Define a custom function that returns
    # the sum(column XX) and max(column YY)-min(column YY)
    calc_summary_stats <- function(df) {
        c(sum(df$XX), max(df$YY) - min(df$YY));
    }
    
  3. 使用list将此功能应用于sapply元素,以获得预期结果。

    # Apply the function to the list of dataframes
    m <- t(sapply(lst, calc_summary_stats))
    colnames(m) <- c("XX", "YY");
    #      XX  YY
    #[1,] 3.0 0.4
    #[2,] 6.3 2.1
    #[3,] 5.0 1.4
    #[4,] 8.7 2.4
    
  4. 使用tidyverse

    的方法2

    使用dplyr,我们可以先添加idx列,我们会根据这些列对数据进行分组;然后filter包含&gt; 1行的组,计算每个组的两个摘要统计信息,并输出删除了ungroup列的idx ed数据。

    library(tidyverse);
    df %>%
        mutate(idx = c(rep(1, 2), 2, rep(3, 5), 4, rep(5, 4), 6, rep(7, 5), 8)) %>%
        group_by(idx) %>%
        filter(n() > 1) %>%
        summarise(XX = sum(XX), YY = max(YY) - min(YY)) %>%
        ungroup() %>%
        select(-idx);
    ## A tibble: 4 x 2
    #     XX    YY
    #  <dbl> <dbl>
    #1  3.00 0.400
    #2  6.30 2.10
    #3  5.00 1.40
    #4  8.70 2.40
    

    样本数据

    df <- read.table(text =
        "XX   YY
    1  3.0 23.6
    2  0.0 23.2
    3  0.0 23.7
    4  0.0 25.2
    5  1.3 24.5
    6  4.8 24.2
    7  0.2 23.1
    8  0.0 23.3
    9  0.0 23.9
    10 0.0 24.3
    11 1.8 24.6
    12 3.2 23.7
    13 0.0 23.2
    14 0.0 23.6
    15 0.0 24.1
    16 0.2 24.5
    17 4.8 24.1
    18 3.7 22.1
    19 0.0 23.4
    20 0.0 23.8", header = T)