我对R(这个网站的新用户)相当新,并尝试了解如何在有超过1个标识符的情况下跨列聚合数据(在这种情况下,两个:PERSON_ID和PRODUCT_ID)。 / p>
请参阅下面的示例。在我的数据框中的两个标识符的右侧是包含每周销售数字的五列。我需要汇总每周数据,以便:
1:对具有相同名称的周列进行求和(通常这是我可以使用sumif / sumifs函数在MS Excel中轻松完成的事情)
2:任何包含相同PERSON_ID和PRODUCT_ID组合的行也会相加。
在这种特殊情况下,请注意,2017年2月2日这一周出现在多个列中。同时,对于相同的PRODUCT_ID,3024,PERSON_ID 0003603会出现两次。
PERSON_ID PRODUCT_ID 6/23/2017 6/16/2017 6/9/2017 6/2/2017 6/2/2017
0003603 3024 10.000 5.000 4.000 3.000 2.000
0003603 3024 1.000 2.000 3.000 8.000 1.000
0007654 2111 8.000 3.000 2.000 1.000 0.000
0008885 3025 0.000 0.000 1.000 3.000 9.000
0950645 3024 6.000 5.000 4.000 3.000 2.000
我的实际数据框包含超过100万条记录,因此,据我所知,使用data.table包的方法是理想的。
有人可以说明如何在R中解决这个特殊问题吗?
答案 0 :(得分:2)
melt
你的数据(重塑长)是要走的路。如果我理解了你正确的事情,那就简单地说:
x = fread('PERSON_ID PRODUCT_ID 6/23/2017 6/16/2017 6/9/2017 6/2/2017 6/2/2017
0003603 3024 10.000 5.000 4.000 3.000 2.000
0003603 3024 1.000 2.000 3.000 8.000 1.000
0007654 2111 8.000 3.000 2.000 1.000 0.000
0008885 3025 0.000 0.000 1.000 3.000 9.000
0950645 3024 6.000 5.000 4.000 3.000 2.000',
colClasses = c('character', 'character', rep('numeric', 5L)))
xmlt =
melt(x, id.vars = c('PERSON_ID', 'PRODUCT_ID'),
variable.name = 'week', value.name = 'sales')
xmlt[ , week := as.IDate(week, format = '%m/%d/%Y')]
xmlt[ , .(total_sales = sum(sales)),
keyby = .(PERSON_ID, PRODUCT_ID, week)]
PERSON_ID PRODUCT_ID week total_sales
# 1: 0003603 3024 2017-06-02 14
# 2: 0003603 3024 2017-06-09 7
# 3: 0003603 3024 2017-06-16 7
# 4: 0003603 3024 2017-06-23 11
# 5: 0007654 2111 2017-06-02 1
# 6: 0007654 2111 2017-06-09 2
# 7: 0007654 2111 2017-06-16 3
# 8: 0007654 2111 2017-06-23 8
# 9: 0008885 3025 2017-06-02 12
# 10: 0008885 3025 2017-06-09 1
# 11: 0008885 3025 2017-06-16 0
# 12: 0008885 3025 2017-06-23 0
# 13: 0950645 3024 2017-06-02 5
# 14: 0950645 3024 2017-06-09 4
# 15: 0950645 3024 2017-06-16 5
# 16: 0950645 3024 2017-06-23 6
答案 1 :(得分:0)
我们首先定义df
如下。请注意,R
中的列名不能以数字开头,也不能重复。 R
通过在以列号开头的列名前面添加X
并在列名末尾添加.1
,.2
等来更正这些内容。< / p>
df <- read.table(text = "
PERSON_ID PRODUCT_ID 6/23/2017 6/16/2017 6/9/2017 6/2/2017 6/2/2017
0003603 3024 10.000 5.000 4.000 3.000 2.000
0003603 3024 1.000 2.000 3.000 8.000 1.000
0007654 2111 8.000 3.000 2.000 1.000 0.000
0008885 3025 0.000 0.000 1.000 3.000 9.000
0950645 3024 6.000 5.000 4.000 3.000 2.000",
header = TRUE, colClasses = rep(c("character", "numeric"), c(2,5)))
我们可以使用dplyr
(数据操作),tidyr
(整洁的数据)和lubridate
(使用日期)包来解决问题。
library(dplyr)
library(tidyr)
library(lubridate)
library(rebus)
df %>%
gather(DATE, SALES, -c(PERSON_ID, PRODUCT_ID)) %>%
mutate(DATE = str_extract(DATE, pattern = repeated(DGT, 1, 2) %R% DOT %R%
repeated(DGT, 1, 2) %R% DOT %R%
repeated(DGT, 4, 4)),
DATE = mdy(DATE)) %>%
group_by(PERSON_ID, PRODUCT_ID, DATE) %>%
summarise_at(vars(SALES), funs(sum)) %>%
ungroup
代码以下列方式编写:
df
转换为长格式。这是为了确保数据框中的行是观察值,列是变量。DATE
变量以删除前缀X
和后缀.1
,并将日期类(月 - 日 - 年)强制转换为变量。PERSON_ID
,PRODUCT_ID
,DATE
SALES
变量求和(在上一点中定义)如果您想将其转换回宽幅广告,可以在最后添加另一行,即%>% spread(DATE, SALES)
。