Identifique a data de uma alteração de valor e resuma os dados com sum () e diff () em R
Dados de amostra:
product_id <- c("1000","1000","1000","1000","1000","1000", "1002","1002","1002","1002","1002","1002")
qty_ordered <- c(1,2,1,1,1,1,1,2,1,2,1,1)
price <- c(2.49,2.49,2.49,1.743,2.49,2.49, 2.093,2.093,2.11,2.11,2.11, 2.97)
date <- c("2/23/15","2/23/15", '3/16/15','3/16/15','5/16/15', "6/18/15", "2/19/15","3/19/15","3/19/15","3/19/15","3/19/15","4/19/15")
sampleData <- data.frame(product_id, qty_ordered, price, date)
Gostaria de identificar sempre que ocorreu uma alteração no preço. Além disso, gostaria de somar () o total qty_ordered entre essas duas datas de alteração de preço. Por exemplo, paraproduct_id == "1000"
, o preço foi alterado em 16/3/15 de US $ 2,49 para US $ 1,743. O total qty_ordered é 1 + 2 + 1 = 4; a diferença entre essas duas primeiras datas de alteração de preço é de 23/2/15 a 16/3/15, ou seja, 21 dias.
Portanto, o novo quadro de dados deve ser:
product_id sum_qty_ordered price date_diff
1000 4 2.490 21
1000 1 1.743 61
1000 2 2.490 33
Aqui está o que eu tentei:
** NOTA: para este caso, um simples "dplyr::group_by
"não funcionará, pois ignorará o efeito da data.
1) Encontrei este código deDetermine quando as colunas de um data.frame alteram o valor e retornam índices da alteração: É para identificar sempre que o preço foi alterado, que identifica a primeira data em que o preço foi alterado para cada produto.
IndexedChanged <- c(1,which(rowSums(sapply(sampleData[,3],diff))!=0)+1)
sampleData[IndexedChanged,]
No entanto, não sei como calcular osum(qty_ordered)
e a diferença de data para cada uma dessas entradas, se eu usar esse código.
2) Tentei escrever um loop WHILE para armazenar temporariamente cada lote deproduct_id
, preço, intervalo de datas (por exemplo, um subconjunto de quadros de dados com umproduct_id
, um preço e todas as entradas variaram desde a data mais antiga da alteração de preço até a última data do preço antes da alteração) e, em seguida, resuma o subconjunto para obter a soma (sum_qty_ordered
) e a data diff. No entanto, acho que sempre fico confuso com WHILE e FOR, então meu código tem alguns problemas. Aqui está o meu código:
crie um quadro de dados vazio para armazenamento de dados posterior
NewData_Ready <- data.frame(
product_id = character(),
price = double(),
early_date = as.Date(character()),
last_date=as.Date(character()),
total_qty_demanded = double(),
stringsAsFactors=FALSE)
crie uma tabela temporária para armazenar as entradas de ordem de preço de lote
temp_dataset <- data.frame(
product_id = character(),
qty_ordered = double(),
price = double(),
date=as.Date(character()),
stringsAsFactors=FALSE)
loop: Isso é confuso ... e provavelmente não faz sentido, então eu realmente ajudo nisso.
for ( i in unique(sampleData$product_id)){
#for each unique product_id in the dataset, we are gonna loop through it based on product_id
#for first product_id which is "1000"
temp_table <- sampleData[sampleData$product_id == "i", ] #subset dataset by ONE single product_id
#this dataset only has product of "1000" entries
#starting a new for loop to loop through the entire entries for this product
for ( p in 1:length(temp_table$product_id)){
current_price <- temp_table$price[p] #assign current_price to the first price value
#assign $2.49 to current price.
min_date <- temp_table$date[p] #assign the first date when the first price change
#assign 2015-2-23 to min_date which is the earliest date when price is $2.49
while (current_price == temp_table$price[p+1]){
#while the next price is the same as the first price
#that is, if the second price is $2.49 is the same as the first price of $2.49, which is TRUE
#then execute the following statement
temp_dataset <- rbind(temp_dataset, temp_table[p,])
#if the WHILE loop is TRUE, means every 2 entries have the same price
#then combine each entry when price is the same in temp_table with the temp_dataset
#if the WHILE loop is FALSE, means one entry's price is different from the next one
#then stop the statement at the ab,ove, but do the following
current_price <- temp_table$price[p+1]
#this will reassign the current_price to the next price, and restart the WHILE loop
by_idPrice <- dplyr::group_by(temp_dataset, product_id, price)
NewRow <- dplyr::summarise(
early_date = min(date),
last_date = max(date),
total_qty_demanded = sum(qty_ordered))
NewData_Ready <- rbind(NewData_Ready, NewRow)
}
}
}
Pesquisei bastante questões relacionadas, mas ainda não encontrei nada relacionado a esse problema. Se você tiver algumas sugestões, entre em contato. Além disso, forneça algumas sugestões sobre a solução para minhas perguntas. Eu apreciaria muito seu tempo e ajuda!
Here is my R version:
platform x86_64-apple-darwin13.4.0
arch x86_64
os darwin13.4.0
system x86_64, darwin13.4.0
status
major 3
minor 3.1
year 2016
month 06
day 21
svn rev 70800
language R
version.string R version 3.3.1 (2016-06-21)
nickname Bug in Your Hair