以下数据将帮助创建以下问题的示例:
df1 <- data.frame(ID = c(1:5), Order_status_1 = c(1,1,0,0,1), Order_time_1 = c(20, 30, 0, 0, 47),
Order_status_1 = c(0,1,1,1,1), Order_time_1 = c(0, 36, 12, 24, 88), Order_status_3 = c(0, 1, 1, 0,
0), Order_time_3 = c(0, 40, 25, 0, 0), Order_status_4 = c(0, 1, 0, 0, 0), Order_time_3 = c(0, 65, 0,
0, 0), Order_close_date = c(100, 200, 300, 400, 500) )
df2 <- data.frame(ID = c(1:5), Order_status_1 = c(1,1,0,0,1), Order_time_1 = c(20, 30, 0, 0, 47),
Order_status_2 = c(0,1,1,1,1), Order_time_2 = c(100, 36, 12, 24, 88), Order_status_3 = c(0, 1, 1, 0,
0), Order_time_3 = c(100, 40, 25, 400, 500), Order_status_4 = c(0, 1, 0, 0, 0), Order_time_4 =
c(100, 65, 300, 400, 500), Order_close_date = c(100, 200, 300, 400, 500) )
如您所见,最后(时间)列中的值被复制到非零时间值列之后的包含0->的时间列中。
我强烈认为循环应该从最后一列开始检查(0),直到达到非零值,然后将值(100,200,300,400,500)插入各个单元格中。数据包含多行,这只是其中的一个示例。因此,请提供解决方案(例如for或if循环),该解决方案可以将代码运行超过1000行。
答案 0 :(得分:1)
使用data.table
转换为长格式,更新适当的行,然后根据所需的输出转换为宽格式的选项:
library(data.table)
#convert into long format
DT <- melt(setDT(df1), id.vars=c("ID", "Order_close_date"),
measure.vars=patterns("^Order_status", "^Order_time"),
value.name=c("Order_status", "Order_time"),
variable.name="Order", variable.factor=FALSE)
#update rows where Order_status is 0 and there is a 1 before then
DT[DT[, .I[Order_status==0 & cumsum(Order_status) > 0], ID]$V1,
Order_time := Order_close_date]
#pivot into wide format
ans <- dcast(DT, ID + Order_close_date ~ Order, value.var=c("Order_status","Order_time"))
setcolorder(ans, names(df1))[]
输出:
ID Order_status_1 Order_time_1 Order_status_2 Order_time_2 Order_status_3 Order_time_3 Order_status_4 Order_time_4 Order_close_date
1 1 1 20 0 100 0 100 0 100 100
2 2 1 30 1 36 1 40 1 65 200
3 3 0 0 1 12 1 25 0 300 300
4 4 0 0 1 24 0 400 0 400 400
5 5 1 47 1 88 0 500 0 500 500
答案 1 :(得分:1)
在基数R中,我们可以在apply
列上逐行使用"time"
,并用最后一个列值替换第一次出现非零值之后的0。
time_columns <- c(grep("time", names(df1)), ncol(df1))
df1[time_columns] <- t(apply(df1[time_columns], 1, function(x)
replace(x, x == 0 & seq_along(x) > which.max(x !=0), x[length(x)])))