R:递归添加行

问题描述

j 个表面接触后手部细菌的浓度可以由以下递归关系决定:

H[j+1]=H[j]+T[j]*(S[j]-H[j])

其中 S 是手触摸的表面浓度(为方便起见假定为随机)。 T 是每个联系人的传输效率。我想计算最终的手部浓度(起始浓度为零)。

我有一个数据框,其中包含每个表面的表面接触向量和传输效率。我有两个组 ab,并且在每个组中假设我将依次触摸每个 1:length(df)

 df <- data.frame(S = runif(10)*100,T = runif(10),g=rep(c("a","b"),each=5))

我想在可能的情况下使用 H 按组计算 dplyr 的累积总和。

特殊情况:

如果是 g = "a",则 H 的起始值为 0。 如果 g=="b"H 的起始值是 g=="a"

时的最后一个

解决方法

为了完整性和从 Arun 和 Onyambu 那里获取线索(在一个单独的问题上),我也在此处添加 baseR 答案。

transform(df,H = Reduce(function(.x,.y) .x + df$T[.y] * (df$S[.y] - .x) * !c(!duplicated(df$g)[-1],0)[.y],seq(nrow(df)),init = 0,accumulate = TRUE)[-(1 + nrow(df))])

           S         T g        H
1  37.698250 0.8550377 a  0.00000
2   3.843585 0.4722659 a 32.23342
3  33.150788 0.3684791 a 18.82587
4   8.948116 0.8893603 a 24.10430
5  57.061844 0.5452377 a 10.62499
6  49.648827 0.7719067 b 10.62499
7  95.403697 0.5835950 b 40.74775
8  10.598677 0.1220491 b 72.64469
9  91.913365 0.2166443 b 65.07203
10 69.644200 0.2603413 b 70.88705

较早的回答 上面我朋友的回答略有不同,我希望这可以满足您的目的。我唯一的假设是您的数据已经按组排序并且 ab 之前(完全如示例所示)。既然你没有给随机种子,我也拿我朋友拿的一样的数据。

  • 策略/技巧,我在 0 参数中使用了 Taccumulate2 值,以便 H 组中 a 的最后一个值在第一个值中重复b
library(tidyverse)

df <- read.table(header = TRUE,text = '           S         T g
1  37.698250 0.8550377 a
2   3.843585 0.4722659 a
3  33.150788 0.3684791 a
4   8.948116 0.8893603 a
5  57.061844 0.5452377 a
6  49.648827 0.7719067 b
7  95.403697 0.5835950 b
8  10.598677 0.1220491 b
9  91.913365 0.2166443 b
10 69.644200 0.2603413 b')

df %>%
  mutate(H = accumulate2(S,replace(T,length(g[g=='a']),0),.init = 0,~ ..1 + ..3 * (..2 - ..1))[-(1+n())])


           S         T g        H
1  37.698250 0.8550377 a  0.00000
2   3.843585 0.4722659 a 32.23342
3  33.150788 0.3684791 a 18.82587
4   8.948116 0.8893603 a 24.10430
5  57.061844 0.5452377 a 10.62499
6  49.648827 0.7719067 b 10.62499
7  95.403697 0.5835950 b 40.74775
8  10.598677 0.1220491 b 72.64469
9  91.913365 0.2166443 b 65.07203
10 69.644200 0.2603413 b 70.88705

#check - formula
#H[j+1]=H[j]+T[j]*(S[j]-H[j])
# for j =2
# H[2] = H[1] + T[1] * (S[1] -H[1])

0 + 0.8550377 * (37.698250 - 0)
#> [1] 32.23342

#for j=7 (second row group b)

#H[6] + T[6] * (S[6] - H[6])
10.62499 + 0.7719067 * (49.648827 - 10.62499)
#> [1] 40.74775

reprex package (v2.0.0) 于 2021 年 7 月 10 日创建

,

这是@AnilGoyal 针对一般情况展示的类似方法

library(dplyr)
library(purrr)
df %>%
    mutate(H = accumulate2(S,T* !lead(!duplicated(g),default = FALSE),~ ..1 + ..3 * (..2 - ..1))[-n()])
,

这是我将用于此问题的另一个通用版本:

df$H <- Reduce(function(x,y) {
  x + df$T[y] * (df$g[y] == df$g[y + 1]) * (df$S[y] - x) 
},seq_len(nrow(df))[-nrow(df)],accumulate = TRUE)

df

           S         T g        H
1  37.698250 0.8550377 a  0.00000
2   3.843585 0.4722659 a 32.23342
3  33.150788 0.3684791 a 18.82587
4   8.948116 0.8893603 a 24.10430
5  57.061844 0.5452377 a 10.62499
6  49.648827 0.7719067 b 10.62499
7  95.403697 0.5835950 b 40.74775
8  10.598677 0.1220491 b 72.64469
9  91.913365 0.2166443 b 65.07203
10 69.644200 0.2603413 b 70.88705

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...