我有12栏:
11是"day0","day1“。"day10“在df中称为”预测“
1是df中的"within10closures“,称为”人数“。
两个外勤部的长度相同。
我希望在预测$10的时候减去10闭包中的人头数$,除非它达到0,在这种情况下,我希望它从day9中减去余数,以此类推,直到到达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循环来做同样的事情,但是在那里我可以控制哪些列的范围到减法,但是我真的不知道我在做什么,它根本没有得到正确的数字(抱歉,代码太乱了):
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发布于 2017-11-23 15:39:39
更新后审查:
数据:
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时,wwe希望显示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(预测)-1如果需要使用0:(ncol(forecasting)-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,只有在正的情况下才使用它,如果不是,则保留负值,即使它大于10。例如:您可能会得到类似于-35 0 0 0的行。
https://stackoverflow.com/questions/47457855
复制相似问题