【问题标题】:Rolling sum from a certain position in a data frame in R从R中数据框中的某个位置滚动总和
【发布时间】:2018-08-22 07:01:59
【问题描述】:

假设我有以下数据,dat1;

width  from  by
2      1     A
3      1     A
2      2     A
3      2     A
2      1     B
3      1     B
2      2     B
3      2     B

另外还有那个,dat2;

x      pos   by
4      1     A
5      2     A
7      3     A
3      4     A
2      1     B
4      2     B
3      3     B
5      4     B

假设我想在 dat1 上创建一个来自 dat2 where 的滚动总和值的新列;

  1. 我们这个滚动总和的宽度等于该行给定的宽度

  2. 我们的起始位置相当于该行中的from向量值

  3. 我们希望为 A 或 Bth 因子执行此操作,具体取决于行中的哪个级别

到目前为止,我有我们想要的

rollapply(x = dat2$x, width = dat1$width, FUN = sum, align = "left", data = dat2)

所以我需要将起始位置和该起始位置的因子水平结合起来。

所以在这种情况下我想得到

width  from  by   RS
2      1     A    9
3      1     A    16
2      2     A    12
3      2     A    15

任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: r rollapply


    【解决方案1】:

    1) 对于dat1 中的每一行i,匿名函数子集dat2 为dat1 中的by 值,并从中挑选出x 和总结他们:

    transform(dat1, RS = sapply(1:nrow(dat1), function(i) 
     sum(subset(dat2, dat1$by[i] == by)[seq(from[i], length = width[i]), "x"])))
    

    给予:

      width from by RS
    1     2    1  A  9
    2     3    1  A 16
    3     2    2  A 12
    4     3    2  A 15
    5     2    1  B  6
    6     3    1  B  9
    7     2    2  B  7
    8     3    2  B 12
    

    2) 另一种方法是计算要在dat2 中求和的序列的起始值和宽度,然后应用:

    st <- match(dat1$by, dat2$by) + dat1$from - 1
    w <- dat1$width
    Sum <- function(st, w) sum(dat2[seq(st, length = w), "x"])
    transform(dat1, RS = mapply(Sum, st, w))
    

    给予:

      width from by RS
    1     2    1  A  9
    2     3    1  A 16
    3     2    2  A 12
    4     3    2  A 15
    5     2    1  B  6
    6     3    1  B  9
    7     2    2  B  7
    8     3    2  B 12
    

    注意

    dat1dat2 的可重现形式是:

    Lines1 <- "
    width  from  by
    2      1     A
    3      1     A
    2      2     A
    3      2     A
    2      1     B
    3      1     B
    2      2     B
    3      2     B"
    dat1 <- read.table(text = Lines1, header = TRUE)
    
    Lines2 <- "
    x      pos   by
    4      1     A
    5      2     A
    7      3     A
    3      4     A
    2      1     B
    4      2     B
    3      3     B
    5      4     B"
    dat2 <- read.table(text = Lines2, header = TRUE)
    

    更新

    固定 (1)。已添加 (2)。

    【讨论】:

      【解决方案2】:

      另一个选项可能是使用dplyrjoin。该方法将是join 两个数据帧由“by”。然后应用filter 仅考虑pos 介于fromfrom+width 之间的那些行。最后取x 列的总和。

      dat1 %>% inner_join(dat2, by = "by") %>%
        filter(from <= pos & pos < (from + width) ) %>%
        group_by(by, from, width ) %>%
        summarise(RS = sum(x)) %>%
        select(width, from, by, RS)
      
      
      # A tibble: 8 x 4
      # Groups: by, from [4]
      # width  from by       RS
      # <int> <int> <chr> <int>
      # 1     2     1 A         9
      # 2     3     1 A        16
      # 3     2     2 A        12
      # 4     3     2 A        15
      # 5     2     1 B         6
      # 6     3     1 B         9
      # 7     2     2 B         7
      # 8     3     2 B        12
      

      数据

      dat1 <- read.table(text = 
      "width  from  by
      2      1     A
      3      1     A
      2      2     A
      3      2     A
      2      1     B
      3      1     B
      2      2     B
      3      2     B", header = TRUE, stringsAsFactors = FALSE)
      
      
      dat2 <- read.table(text = 
      "x      pos   by
      4      1     A
      5      2     A
      7      3     A
      3      4     A
      2      1     B
      4      2     B
      3      3     B
      5      4     B", header = TRUE, stringsAsFactors = FALSE)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-02
        • 1970-01-01
        • 2011-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多