我需要重新格式化表格。该表看起来像:
date ItemID NewPrice Sale Amount
1-1 1 5 3
1-1 2 8 2
1-1 3 3 5
1-2 1 6 4
1-2 3 4 3
1-3 2 7 2
1-3 3 2 1
我要重新制定的第一个表格如下:
date item_1 item_2 item_3
1-1 3 2 5
1-2 4 0 3
1-3 0 2 1
项目ID成为列名称,值为销售额。棘手的部分是,有些日子里,某些项目没有记录,就像1-2中第2项没有项目记录一样。在这种情况下,销售金额应填写为0。
我想重新拟定的第二个表格如下:
date item_1 item_2 item_3
1-1 5 8 3
1-2 6 8 4
1-3 6 7 2
所以我想要做的是使用item_id作为列,并使用NewPrice作为每个日期的值。
棘手的部分是,在每一天,总会有一些项目没有出现,所以当天没有NewPrice这个项目。在这种情况下,NewPrice应该是最后一天的NewPrice。
答案 0 :(得分:3)
以下是第一部分的基础R解决方案:
xtabs(`Sale Amount` ~ date + ItemID, DF)
## ItemID
## date 1 2 3
## 1-1 3 2 5
## 1-2 4 0 3
## 1-3 0 2 1
对于第二部分,我们在na.locf
的动物园中使用tapply
。如果第一个日期有NA,则na.rm = FALSE
。在这种情况下,我们将其保留为NA。
library(zoo)
na.locf(tapply(DF$NewPrice, DF[c("date", "ItemID")], c), na.rm = FALSE)
## ItemID
## date 1 2 3
## 1-1 5 8 3
## 1-2 6 8 4
## 1-3 6 7 2
注意:可重复形式的输入DF
为:
Lines <- "date ItemID NewPrice 'Sale Amount'
1-1 1 5 3
1-1 2 8 2
1-1 3 3 5
1-2 1 6 4
1-2 3 4 3
1-3 2 7 2
1-3 3 2 1"
DF <- read.table(text = Lines, header = TRUE, check.names = FALSE)
答案 1 :(得分:2)
reshape2
的后继者是tidyr
,它与dplyr
很好地整合。你的第一个案例非常简单:
library(dplyr)
library(tidyr)
# get rid of excess column
df %>% select(-NewPrice) %>%
# fix labels so they'll make nice column names
mutate(ItemID = paste0('item_', ItemID)) %>%
# spread from long to wide, filling with 0 instead of NA
spread(ItemID, Sale.Amount, fill = 0)
# date item_1 item_2 item_3
# 1 1-1 3 2 5
# 2 1-2 4 0 3
# 3 1-3 0 2 1
对于第二个,请明确使用fill
代替spread
中的参数:
# get rid of excess column
df %>% select(-Sale.Amount) %>%
# fix labels so they'll make nice column names
mutate(ItemID = paste0('item_', ItemID)) %>%
# spread from long to wide
spread(ItemID, NewPrice) %>%
# fill NA values with previous value
fill(-date)
# date item_1 item_2 item_3
# 1 1-1 5 8 3
# 2 1-2 6 8 4
# 3 1-3 6 7 2
答案 2 :(得分:2)
使用dcast
library(data.table)
dcast(setDT(dfN), date~paste0("item_", ItemID), value.var="Sale.Amount", fill=0)
# date item_1 item_2 item_3
#1: 1-1 3 2 5
#2: 1-2 4 0 3
#3: 1-3 0 2 1
对于第二种情况,我们可以使用na.locf
将NA值替换为之前的非NA值(在使用dcast
重新形成'wide'之后)。
library(zoo)
dcast(setDT(dfN), date~paste0("item_", ItemID), value.var="NewPrice")[,
(2:4) := lapply(.SD, na.locf), .SDcols = item_1:item_3][]
# date item_1 item_2 item_3
#1: 1-1 5 8 3
#2: 1-2 6 8 4
#3: 1-3 6 7 2