присвоение значений конкретным ячейкам на основе значений в определенном столбце - PullRequest
0 голосов
/ 04 октября 2019

вот те данные, которые помогут создать образец для вопроса, заданного ниже:

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

Как вы можете видеть значение в последнем (times) столбец копируется в столбец times, содержащий 0 -> после столбца значений времени, отличного от нуля.

Я чувствую, что цикл должен начать проверку (0), начиная с последнего столбца времени, пока он не достигнет ненулевого значения, а затем вставить значение (100,200,300,400,500) в соответствующие ячейки. Данные содержат несколько строк, и это только пример из них. Так что любезно предоставьте решение (пример - для циклов if или if), которое может выполнить код для более чем 1000 строк.

Ответы [ 2 ]

1 голос
/ 04 октября 2019

В базе R мы можем использовать apply построчно для столбцов "time" и заменять 0 после 1-го появления ненулевого значения последним значением столбца.

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)])))
1 голос
/ 04 октября 2019

Параметр, использующий 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...