【发布时间】:2017-03-03 21:02:31
【问题描述】:
这个帖子是我之前的帖子 Join then mutate using data.table without intermediate table 的延续。
在那个线程中,我使用查找表来更改收入和数量,然后将结果除以.N,这样当我汇总产品时,我就不会看到虚增的值。
根据该线程专家的建议,我不想指望用于连接的所有四个变量,即PO_ID、SO_ID、F_Year、Product_ID,但只有SO_ID, F_Year,Product_ID。
问题:我怎样才能使用data.table做到这一点?
这是我的数据和代码:
这是我使用dplyr的数据和解决方案
输入
DFI = structure(list(PO_ID = c("P1234", "P1234", "P1234", "P1234",
"P1234", "P1234", "P2345", "P2345", "P3456", "P4567"), SO_ID = c("S1",
"S1", "S2", "S2", "S2", "S2", "S3", "S3", "S7", "S10"), F_Year = c(2012,
2012, 2013, 2013, 2013, 2013, 2011, 2011, 2014, 2015), Product_ID = c("385X",
"385X", "450X", "450X", "450X", "900X", "3700", "3700", "A11U",
"2700"), Revenue = c(1, 2, 3, 34, 34, 6, 7, 88, 9, 100), Quantity = c(1,
2, 3, 8, 8, 6, 7, 8, 9, 40), Location1 = c("MA", "NY", "WA",
"NY", "WA", "NY", "IL", "IL", "MN", "CA")), .Names = c("PO_ID",
"SO_ID", "F_Year", "Product_ID", "Revenue", "Quantity", "Location1"
), row.names = c(NA, 10L), class = "data.frame")
查表
DF_Lookup = structure(list(PO_ID = c("P1234", "P1234", "P1234", "P2345",
"P2345", "P3456", "P4567"), SO_ID = c("S1", "S2", "S2", "S3",
"S4", "S7", "S10"), F_Year = c(2012, 2013, 2013, 2011, 2011,
2014, 2015), Product_ID = c("385X", "450X", "900X", "3700", "3700",
"A11U", "2700"), Revenue = c(50, 70, 35, 100, -50, 50, 100),
Quantity = c(3, 20, 20, 20, -10, 20, 40)), .Names = c("PO_ID",
"SO_ID", "F_Year", "Product_ID", "Revenue", "Quantity"), row.names = c(NA,
7L), class = "data.frame")
这是我使用dplyr修改后的代码:
DF_Generated <- DFI %>%
left_join(DF_Lookup,by = c("PO_ID", "SO_ID", "F_Year", "Product_ID")) %>%
dplyr::group_by(SO_ID, F_Year, Product_ID) %>%
dplyr::mutate(Count = n()) %>%
dplyr::ungroup()%>%
dplyr::mutate(Revenue = Revenue.y/Count, Quantity = Quantity.y/Count) %>%
dplyr::select(PO_ID:Product_ID,Location1,Revenue,Quantity)
请注意group_by 的输入已更改。
预期输出:
DF_Generated = structure(list(PO_ID = c("P1234", "P1234", "P1234", "P1234",
"P1234", "P1234", "P2345", "P2345", "P3456", "P4567"), SO_ID = c("S1",
"S1", "S2", "S2", "S2", "S2", "S3", "S3", "S7", "S10"), F_Year = c(2012,
2012, 2013, 2013, 2013, 2013, 2011, 2011, 2014, 2015), Product_ID = c("385X",
"385X", "450X", "450X", "450X", "900X", "3700", "3700", "A11U",
"2700"), Location1 = c("MA", "NY", "WA", "NY", "WA", "NY", "IL",
"IL", "MN", "CA"), Revenue = c(25, 25, 23.3333333333333, 23.3333333333333,
23.3333333333333, 35, 50, 50, 50, 100), Quantity = c(1.5, 1.5,
6.66666666666667, 6.66666666666667, 6.66666666666667, 20, 10,
10, 20, 40)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-10L), .Names = c("PO_ID", "SO_ID", "F_Year", "Product_ID", "Location1",
"Revenue", "Quantity"))
注意:请注意,我不想创建中间变量,因为实际数据量太大,这可能不可行。
【问题讨论】:
-
你试过什么,为什么没用?
-
@mtoto - 我尝试使用
dplyr,这是我在上面发布的。正如我们所说,我仍在尝试使用data.table来完成它,并且不断出错。正如我所说,我是初学者,对data.table不是很熟悉。 -
我猜,加入第四列并没有什么意义。如果我把它排除在连接之外,我会得到你想要的结果:
DFI[DF_Lookup, on=.(SO_ID, F_Year, Product_ID), `:=`(nr = i.Revenue/.N, nq = i.Quantity/.N), by=.EACHI][] -
@Frank - 感谢您的帮助,但这取决于这三列是复合键。在我的实际数据中并非如此。要我更改查找表并重新发布吗?
-
当然,我不是 sql 大师,所以不知道复合性在这里有多重要。
标签: r data.table dplyr