首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >柱间累积减法

柱间累积减法
EN

Stack Overflow用户
提问于 2017-11-23 14:33:01
回答 1查看 538关注 0票数 1

我有12栏:

11是"day0","day1“。"day10“在df中称为”预测“

1是df中的"within10closures“,称为”人数“。

两个外勤部的长度相同。

我希望在预测$10的时候减去10闭包中的人头数$,除非它达到0,在这种情况下,我希望它从day9中减去余数,以此类推,直到到达day0为止。

目前,我有下面的代码--虽然它很长,而且可能不是最有效的方法--但我想对多个列进行相同的过程,这些列的数目各不相同。希望这能解释我想做的事。

代码语言:javascript
复制
for(i in 1:i) if(forecasting$day10[i]>headcount$within10closures[i]){
  forecasting$day10[i] <- forecasting$day10[i] - headcount$within10closures[i]
} else {
  forecasting$day10[i] <- 0
  subtraction <- headcount$within10closures[i]-forecasting$day10[i]
  if(forecasting$day9[i]>subtraction){
    forecasting$day9[i] - (subtraction)
  } else {
    forecasting$day9[i] <- 0
    subtraction <- subtraction - forecasting$day9[i]
    if(forecasting$day8[i]>subtraction){
      forecasting$day8[i] - (subtraction)
    } else {
      forecasting$day8[i] <- 0
      subtraction <- subtraction - forecasting$day8[i]
      if(forecasting$day7[i]>subtraction){
        forecasting$day7[i] - (subtraction)
      } else {
        forecasting$day7[i] <- 0
        subtraction <- subtraction - forecasting$day7[i]
        if(forecasting$day6[i]>subtraction){
          forecasting$day6[i] - (subtraction)
        } else {
          forecasting$day6[i] <- 0
          subtraction <- subtraction - forecasting$day6[i]
          if(forecasting$day5[i]>subtraction){
            forecasting$day5[i] - (subtraction)
          } else {
            forecasting$day5[i] <- 0
            subtraction <- subtraction - forecasting$day5[i]
            if(forecasting$day4[i]>subtraction){
              forecasting$day4[i] - (subtraction)
            } else {
              forecasting$day4[i] <- 0
              subtraction <- subtraction - forecasting$day4[i]
              if(forecasting$day3[i]>subtraction){
                forecasting$day3[i] - (subtraction)
              } else {
                forecasting$day3[i] <- 0
                subtraction <- subtraction - forecasting$day3[i]
                if(forecasting$day2[i]>subtraction){
                  forecasting$day2[i] - (subtraction)
                } else {
                  forecasting$day2[i] <- 0
                  subtraction <- subtraction - forecasting$day2[i]
                  if(forecasting$day1[i]>subtraction){
                    forecasting$day1[i] - (subtraction)
                  } else {
                    forecasting$day2[i] <- 0
                    subtraction <- subtraction - forecasting$day2[i]
                    forecasting$day1 <- forecasting$day1 - subtraction
                  }
          }
        }
      }
    }
  }
      }
    }
  }
}

我尝试创建一个for循环来做同样的事情,但是在那里我可以控制哪些列的范围到减法,但是我真的不知道我在做什么,它根本没有得到正确的数字(抱歉,代码太乱了):

代码语言:javascript
复制
for(x in 1:11){
    for(i in 1:n){
    ifelse(x==1, subtraction <- headcount$within10closures[i], subtraction <- (subtraction - (forecasting[i,grep("day10", colnames(forecasting))+1-x])))    
    ifelse(forecasting[i,grep("day10", colnames(forecasting))+1-x]>=subtraction, forecasting[i,grep("day10", colnames(forecasting))+1-x] <- forecasting[i,grep("day10", colnames(forecasting))+1-x] - subtraction, forecasting[i,grep("day10", colnames(forecasting))+1-x] <- 0)
    }    
  }

本质上,我要问的是,如何根据另一列的值,有效地在列之间累计减去,同时控制要减去的列数?

简化输入:

预测:(值可以是任意数字)

代码语言:javascript
复制
day0 | day1 | day2 | day3    
-----+------+------+------
1    |  2   |  4   |  18
10   |  10  |  10  |  10
7    |  10  |  10  |  10    

人数:(值可以是任意数字)

代码语言:javascript
复制
| within10closures |
        6
        10
        35

期望的结果:

代码语言:javascript
复制
day0 | day1 | day2 | day3    
-----+------+------+------
1    |  2   |  4   |  12
10   |  10  |  10  |  0
2    |  0   |  0   |  0      

数据

代码语言:javascript
复制
forecasting <- data.frame(matrix(rep(10, 12), nrow = 3))
colnames(forcasting) <- paste0("day", 0:3)

headcount <- data.frame(within10closures = c(6, 10, 35))

编辑:预测数据并不总是全部10,下面作为示例输入:

代码语言:javascript
复制
set.seed(1)
forecasting <- data.frame(matrix(sample(1:10, 12, replace = TRUE), nrow = 3))
colnames(forecasting) <- paste0("day", 0:3)

#   day0 day1 day2 day3
# 1    3   10   10    1
# 2    4    3    7    3
# 3    6    9    7    2
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-23 15:39:39

更新后审查:

数据:

代码语言:javascript
复制
set.seed(1234)
forecasting <- data.frame(
  day0=sample(1:10,4),
  day1=sample(1:10,4),
  day2=sample(1:10,4),
  day3=sample(1:10,4),
  day4=sample(1:10,4)
)
headcount <- data.frame(within10closures=c(6,10,25,12))

> print(forecasting)

  day0 day1 day2 day3 day4
1    2    9    7    3    3
2    6    6    5    9   10
3    5    1    6   10    2
4    8    2    4    6    8

代码:

代码语言:javascript
复制
for (i in 1:length(headcount$within10closures)) {
  v=headcount$within10closures[i]
  tmp <- c()

  if (sum(forecasting[i,]) - v < 0) {
    forecasting[i,] <- c(sum(forecasting[i,]) - v,rep(0,ncol(forecasting) - 1))
  } else {
    for (x in rev(forecasting[i,])) {
      tmp <- c(tmp, ifelse(x - v < 0, 0, x - v ))
      v <- ifelse(v - x < 1, 0, v - x)
    }

    forecasting[i,] <- rev(tmp)
  }
}

基本上,如果值大于行,则对要子字符串的值进行循环,将负值作为第一个元素构建行。

在对应的行上循环反转(rev),并执行差异,如果有比当前值更多的子字符串,则设置为0。

然后从要删除的内容中删除值,如果值小于1 (0或负),则将其设置为0。

最后,反转构建的向量(tmp)并设置为替换原始预测行。

这意味着:

代码语言:javascript
复制
> forecasting
  day0 day1 day2 day3 day4
1    2    9    7    0    0
2    6    6    5    9    0
3   -1    0    0    0    0
4    8    2    4    2    0

先前的答复:

这似乎得到了您想要的,而不是处理这个主版本中的负数,第二个版本如下:

代码语言:javascript
复制
forecasting <- data.frame(day0=rep(10,3),day1=rep(10,3),day2=rep(10,3),day3=rep(10,3))
headcount <- data.frame(within10closures=c(6,10,35))

nb <- rowSums(forecasting)-headcount$within10closures

result <- as.data.frame(t(sapply(nb, function(x) {
    c( 
      rep(10,x%/%10),
      ifelse(10-x%%10==10,0,10-x%%10),
      rep(0 , ( ncol(forecasting) - x%/%10 -1) ) 
    ) 
}
)))
colnames(result) <- paste0("day",1:ncol(forecasting))

首先计算每一行的和,然后减去相应的within10closures值。

现在,对于每个值( sapply循环),我得到了包含满10的列数(普通除法x%/%10)、剩余部分和0的列数,以完成行。

对于余数(x%%10),我们有两种情况,当它的值为0时,wwe希望显示0,而不是10,因此向量构造中的ifelse设置为0,如果得到0,则设置10减去余数。

这就给出了这样一个矩阵:

代码语言:javascript
复制
     [,1] [,2] [,3]
[1,]   10   10    5
[2,]   10   10    0
[3,]   10   10    0
[4,]    6    0    0

要使其返回到data.frame中,我们需要将其转换为t( )并强制它使用as.data.frame将其转换为data.frame,最后一种方法是用day1 to ncol(forecasting)命名列(可以从0命名为ncol(预测)-1如果需要使用0:(ncol(forecasting)-1),请注意这里的括号以获得适当的值,在减法操作发生之前就会扩展范围)。

为了处理负数,我们需要更多的条件,因为-5%%10返回5:

代码语言:javascript
复制
result <- as.data.frame(t(sapply(nb, function(x) {
    c( 
      rep(10,ifelse(x%/%10>-1, x%/%10, 0) ),
      ifelse(x%%10==0,0,ifelse(x >0, 10 - x%%10, x) ),
      rep(0 , ( ncol(forecasting) - ifelse( x%/%10 > -1, x%/%10, 0) - 1 ) ) 
    ) 
}
)))

这里在主除法中增加了一个ifelse,得到0或一个正数,然后删除负数。

在剩余部分上再使用一个ifelse,只有在正的情况下才使用它,如果不是,则保留负值,即使它大于10。例如:您可能会得到类似于-35 0 0 0的行。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47457855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档