时间:2017-11-23 14:33:02

标签: r

我有12列:

11是" day0"," day1" ......" day10"来自一个名为"预测"

的df

1是"在10个限制内"在一个名为" headcount"

两个dfs的长度都相同。

我想从预测$ day10中扣除10个内部的人数$,除非它达到0,在这种情况下我希望它从第9天减去余数,依此类推,直到达到day0。

目前我有下面的代码 - 虽然很长,可能不是最有效的方式 - 似乎工作,但我想做同样的程序,多个列的数量不同。希望它能解释我想要做的事情。

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循环来做同样的事情,但我可以控制哪个列范围到减法,但我不知道我在做什么,它没有&#39 ; t得到正确的数字(为凌乱的代码道歉):

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)
    }    
  }

基本上我要问的是,如何根据另一列的值有效累积减去列,同时控制要减去的列数?

简化输入:
预测:(值可以是任意数字)

day0 | day1 | day2 | day3    
-----+------+------+------
1    |  2   |  4   |  18
10   |  10  |  10  |  10
7    |  10  |  10  |  10    

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

| within10closures |
        6
        10
        35

期望的结果:

day0 | day1 | day2 | day3    
-----+------+------+------
1    |  2   |  4   |  12
10   |  10  |  10  |  0
2    |  0   |  0   |  0      

数据

forecasting <- data.frame(matrix(rep(10, 12), nrow = 3))
colnames(forcasting) <- paste0("day", 0:3)

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

修改 预测数据帧并不总是全部10,请在下面将其视为示例输入:

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

1 个答案:

答案 0 :(得分:5)

更新后审核:

DATAS:

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

代码:

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)并设置为替换原始预测行。

这给出了:

> 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

上一个回答:

这似乎得到你所追求的,而不是处理这个主要版本的负数,下面的第二个版本:

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时,我希望显示0而不是10,所以如果我们得到的话,向量构造中的这个ifelse设置为0 0或10减去余数,如果是正数。

这样就可以使用这样的矩阵:

     [,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(forecasting)-1),可以从0到ncol(forcasting)-1,注意这里的括号以获得正确的值,在减法发生之前消耗范围。)

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

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只剩下-35 0 0 0使用它,只有当它是正数时,如果不是我们保持负值,即使它大于10.即:你可能会得到像self.items.remove(indexPath.row) presenter.deleteUser(user:items[indexPath.row]) tableview.deleteRows(at:[indexPath],with : .fade)

这样的行