【问题标题】:Efficiently iterate over rows to dynamically/sequentially populate variable going down rows有效地迭代行以动态/顺序填充变量向下行
【发布时间】:2018-11-28 19:42:17
【问题描述】:

我正在尝试动态填充一个变量,这需要我引用行。

给出 3 列:timegroupval

我想填充最初为 NA 的第 3、4、7 和 8 行的 val

这是我的玩具数据:

df <- expand.grid(time = rep(c(1,2,3,4)), group = rep(c("A", "B")))
df$val <- c(50,40,NA,NA)

df

> df
     time group val
  1    1     A  50
  2    2     A  40
  3    3     A  NA
  4    4     A  NA
  5    1     B  50
  6    2     B  40
  7    3     B  NA
  8    4     B  NA

我有两个分组变量(timegroup),例如,我需要填充第 3 行 上面的这组规则:

1. Order by group and time (in ascending order)
2. For time = 3, the value of **val** is the arithmetic average of two previous rows; 
   (2a). i.e. the average of time 2 and time 1 values, so it will be 1/2 * (40+50) = 45.
3. For time = 4, the value of **val** is the arithmetic average of two previous rows;
    (3a). i.e. the average of time 3 and time 2 values, so it will be 1/2 * (45+40) = 42.5.

依此类推,直到由 timegroup 变量定义的每个组的最后一行。

我想避免使用循环和引用行索引来实现这一点,并且更喜欢留在 dplyr 内,因为我的其余脚本都在 dplyr 生态系统。有没有一种有效的方法来实现这一点?

【问题讨论】:

  • 你可以做类似df$val[is.na(df$val)] &lt;- somevalue
  • 就我而言,somevalue 必须按顺序填充,所以我不清楚这种方法将如何工作?

标签: r loops dplyr


【解决方案1】:

这不是最干净的解决方案,但它可以完成工作:

df2 = df %>%
    arrange(group, time) %>%
    mutate(val = if_else(is.na(val), (lag(val, n=1) + lag(val, n=2))/2.0, val)) %>%
    mutate(val = if_else(is.na(val), (lag(val, n=1) + lag(val, n=2))/2.0, val))

同样,它并不漂亮,但它似乎工作。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多