如何输出经过多次%数值减少的变量的累积和[R]

g9icjywg  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(128)

我希望评估每天的清洁频率对累积在牛棚地板上的粪便量的重要性。问题是我只能在第一次清洁事件(即粪便第一次减少)后正确计算粪便量,后续计算未能考虑到清洁事件已经发生。
为了尝试,我在R中定义了四个变量和两个常量:

变量

  • “小时”(数字;从1至24)
  • “binclean”(二进制; 0=无清洁事件,1=清洁事件)
  • “不清洁”(数字;变量,存储在没有清洁时畜舍地板中的粪便累积量)
  • “清洁”(数字;包含清洁后畜舍地板上的粪便量)
    常数
  • “totalfeceshour”(250头牛每小时产生的粪便量= 239.5 kg)
  • “H”(刮擦地板后残留在环境中的粪便量=粪便的0.05%)

我创建了一个矩阵来存储所有变量并执行计算。(基R函数),以获得未经任何清理而累积的粪便,并将其存储在noclean变量中。我在ifelse()函数中使用了一个“for循环”来通知清洁事件的发生。clean”变量,到目前为止,我只能在第一次清洁事件后获得地板上正确的粪便量,但此信息不会传递到后续单元格,例如,到一天的第7个小时,地板上有1,676公斤粪便,如果在第8个小时发生清洁事件,则清洁后的粪便总量为(1,676 + 239.5)* 0.05 = 95.8.如果你运行代码,你会看到到第8个小时的粪便量上升到2,155.5(当它应该是95.8 + 239.5 = 335.3后,一个清洁事件已经发生).这是我的代码:

#Constants
totalfeceshour <- 239.5
H <- 1-0.95

#Variables
hour<- 1:24
cleanbin <- c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
              0, 0, 0, 0, 0, 0, 1) #3 scrapes at hours 8, 16 and 
                                   #24. Each value represent an 
                                   #hour of the day.
noclean <- c(Reduce("+", c(totalfeceshour, rep(totalfeceshour, 
             23)), accumulate = TRUE)) #Feces in the environment
clean <- c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)

#Matrix
mtrx <- matrix(data=c(hour, cleanbin, noclean, clean), ncol=4)
colnames(mtrx) <- c("hour", "cleanbin", "noclean", "clean")

#Loop
for(i in 1:length(mtrx[, 2])){
  mtrx[, 4][i] <- ifelse(mtrx[, 2][i] == 0, mtrx[, 3][i], mtrx[,3] 
   [i]*H)
}

mtrx

如果你运行代码,你会发现清理只减少了cleanbin==1所在单元格的粪便量,但是这个信息不会传递到后面的单元格。(“data.table”包),和其他工具,但还没有能够解决这个问题。我能够创建一个Excel工作表,这样做的伎俩,但我希望在R中实现相同的目标。我将非常感谢您在编码方面的帮助。

e5nqia27

e5nqia271#

这里有一个tidyverse(-ish)解决方案,这个解决方案最困难的部分是你不能使用group_mapifelse这样的内置解决方案,因为所有这些选项都是“原子地”工作的a-也就是说,它们对整个列进行操作,而你需要"迭代地“工作,一行一行地构建解决方案。
因为我的工作流程和你的不同,我重命名了你的一些变量,并删除了其他变量。
首先,创建一个包含定义问题的基本信息的数据框。

library(tidyverse)

d <- tibble(
       Hour=1:24,
       FecesProduced=239.5,
       CleaningEvent=Hour %in% c(8, 16, 24),
       CumulativeFeces=ifelse(Hour==1, FecesProduced, NA)
     ) 
d
# A tibble: 24 × 4
    Hour FecesProduced CleaningEvent CumulativeFeces
   <int>         <dbl> <lgl>                   <dbl>
 1     1          240. FALSE                    240.
 2     2          240. FALSE                     NA 
 3     3          240. FALSE                     NA 
 4     4          240. FALSE                     NA 
 5     5          240. FALSE                     NA 
 6     6          240. FALSE                     NA 
 7     7          240. FALSE                     NA 
 8     8          240. TRUE                      NA 
 9     9          240. FALSE                     NA 
10    10          240. FALSE                     NA 
# … with 14 more rows

现在逐步执行第2行到第24行,根据需要填充CumulativeFeces

for(row in 2:nrow(d)) {
  d <- d %>% mutate(
               CumulativeFeces=ifelse(
                                 row_number() == row,
                                 ifelse(
                                   CleaningEvent,
                                   (FecesProduced + lag(CumulativeFeces)) * 0.05,
                                   FecesProduced + lag(CumulativeFeces)
                                  ),
                                 CumulativeFeces
                                )
             )
}

现在,在打印小块时覆盖默认行为,以确保演示解决方案的准确性。

d %>% mutate(CumulativeFeces=num(CumulativeFeces, digits=2))
# A tibble: 24 × 4
    Hour FecesProduced CleaningEvent CumulativeFeces
   <int>         <dbl> <lgl>               <num:.2!>
 1     1          240. FALSE                  239.50
 2     2          240. FALSE                  479.00
 3     3          240. FALSE                  718.50
 4     4          240. FALSE                  958.00
 5     5          240. FALSE                 1197.50
 6     6          240. FALSE                 1437.00
 7     7          240. FALSE                 1676.50
 8     8          240. TRUE                    95.80
 9     9          240. FALSE                  335.30
10    10          240. FALSE                  574.80
# … with 14 more rows

相关问题