我的CSV中的数据看起来像这样..
CUSIP BuyDate SellDate BuyAmount SellAmount Profit DaysHolding Over365Days
037833100 12/1/2015 3/1/2017 45 27 -18 456 1
17275R102 1/28/2016 2/21/2017 28 25 -3 390 1
38259P508 10/29/2015 2/18/2017 39 36 -3 478 1
594918104 3/1/2016 3/2/2017 35 40 5 366 1
68389X105 4/14/2016 2/21/2017 47 37 -10 313 0
037833100 12/11/2015 2/19/2017 46 40 -6 436 1
17275R102 1/12/2016 2/24/2017 29 34 5 409 1
38259P508 12/22/2015 2/20/2017 46 39 -7 426 1
594918104 12/19/2015 2/22/2017 26 36 10 431 1
68389X105 2/13/2016 3/2/2017 33 34 1 383 1
037833100 12/9/2015 2/18/2017 32 37 5 437 1
17275R102 2/13/2016 2/27/2017 48 25 -23 380 1
38259P508 11/30/2015 2/23/2017 45 34 -11 451 1
594918104 11/14/2015 2/27/2017 47 28 -19 471 1
68389X105 2/10/2016 2/17/2017 39 38 -1 373 1
037833100 4/7/2016 3/5/2017 44 29 -15 332 0
17275R102 3/3/2016 2/19/2017 26 36 10 353 0
037833100 11/25/2015 2/17/2017 28 40 12 450 1
037833100 1/10/2016 3/6/2017 35 36 1 421 1
037833100 3/4/2016 2/22/2017 45 25 -20 355 0
38259P508 2/10/2016 3/7/2017 42 40 -2 391 1
38259P509 12/5/2015 2/25/2017 31 39 8 448 1
38259P510 4/7/2016 2/27/2017 27 34 7 326 0
38259P511 3/26/2016 2/17/2017 27 39 12 328 0
17275R102 2/11/2016 2/27/2017 29 39 10 382 1
17275R102 11/24/2015 2/18/2017 45 35 -10 452 1
38259P509 3/29/2016 3/7/2017 46 27 -19 343 0
38259P509 4/5/2016 2/23/2017 38 38 0 324 0
17275R102 2/13/2016 2/26/2017 35 31 -4 379 1
594918104 3/10/2016 3/4/2017 29 28 -1 359 0
17275R102 10/30/2015 2/23/2017 40 30 -10 482 1
17275R102 12/15/2015 3/2/2017 25 38 13 443 1
594918104 2/2/2016 2/22/2017 26 32 6 386 1
594918105 3/8/2016 2/20/2017 26 29 3 349 0
594918106 11/21/2015 3/6/2017 44 38 -6 471 1
594918107 3/21/2016 2/20/2017 48 39 -9 336 0
594918108 12/21/2015 3/5/2017 37 28 -9 440 1
594918109 1/16/2016 3/5/2017 35 33 -2 414 1
594918110 2/8/2016 3/2/2017 41 39 -2 388 1
此文件中有数百万行。我想基于CUSIP对所有交易进行排序,然后根据Profits和Over365Days对小结果进行排序。这是最终结果应该是什么样子的图像。我只是为了效果添加了一些颜色。
我猜它应该是这样的:
# read csv file
mydata = read.csv("AllTrades.csv")
# sort by CUSIP, Over365Days
sortdata <- mtcars[order(CUSIP, Over365Days),]
# aggregate by Profit & 365Days
finalresults <- aggregate(cbind(Profit, Over365Days) ~ CUSIP, data = sortdata, FUN = sum)
我可以在Excel中轻松管理小数据集,但同样,我有数百万行要处理。有人可以给我一些可以做我所描述的示例代码吗?谢谢大家。
答案 0 :(得分:2)
我不得不做一些清理来重现你的数据,但这是之后的结果
清洁部分和我命名变量clean_data
> str(clean_data)
'data.frame': 39 obs. of 8 variables:
$ CUSIP : chr "037833100" "17275R102" "38259P508" "594918104" ...
$ BuyDate : chr "12/1/2015 " "1/28/2016 " "10/29/2015" "3/1/2016 " ...
$ SellDate : chr "3/1/2017 " "2/21/2017" "2/18/2017" "3/2/2017 " ...
$ BuyAmount : num 45 28 39 35 47 46 29 46 26 33 ...
$ SellAmount : num 27 25 36 40 37 40 34 39 36 34 ...
$ Profit : num -18 -3 -3 5 -10 -6 5 -7 10 1 ...
$ DaysHolding: num 456 390 478 366 313 436 409 426 431 383 ...
$ Over365Days: num 1 1 1 1 0 1 1 1 1 1 ...
然后我复制了10x这个集合以提供稍大的数据大小,因此输出会
更有意义并将其命名为new_data
new_data <- plyr::ldply(1:10, function(i){
clean_data
})
由于Excel格式不符合我们之后随时访问数据的方式 操纵和聚合,我以稍微不同的方式存储结果 比你在excel中更好(...相信我......我多年来一直是分析师......它已经习惯了 但现在我永远不会回到数据透视表......)
因此,步骤适用于我们要进行的每个CUSIP&#39; chunk&#39;数据集
仅限于属于该标识集的那些记录。 IE for N unique
CUSIP ids,我们将使用split
创建N [m,j]分段数据子集
方法。我们还将它包装在循环中,以便我们只需要应用我们的
聚合公式一次,但将适用于每个子集。并为每个数据帧
在N个独特的CUSIP id领域,我们将返回一个列表
1)原始分块数据
2)利润
3)总计
out_split <- lapply(split(new_data, new_data$CUSIP), function(i){
list(
data_subset = i, # This is the data unique to the CUSIP id
profit_calc = sum(i[['Profit']]), # This is the sum of profits
total = sum(i[['Over365Days']]) # This is the sum of 365 roll
)
})
现在我们可以通过访问返回的列表中的CUSIP id来调用我们的数据 并找到我们想要的东西。例如:
> out_split$`594918106`
$data_subset
CUSIP BuyDate SellDate BuyAmount SellAmount Profit DaysHolding Over365Days
35 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
74 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
113 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
152 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
191 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
230 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
269 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
308 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
347 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
386 594918106 11/21/2015 3/6/2017 44 38 -6 471 1
$profit_calc
[1] -60
$total
[1] 10
另外,我们可以通过以下方式找到所有计算出的总数: (由于总计在每次迭代中都存储为第3项)
> sapply(out_split, `[[`, 3)
037833100 17275R102 38259P508 38259P509 38259P510 38259P511 594918104 594918105 594918106 594918107 594918108 594918109 594918110 68389X105
50 80 40 10 0 0 40 0 10 0 10 10 10 20
如果我们想看到利润:
> sapply(out_split, `[[`, 2)
037833100 17275R102 38259P508 38259P509 38259P510 38259P511 594918104 594918105 594918106 594918107 594918108 594918109 594918110 68389X105
-410 -120 -230 -110 70 120 10 30 -60 -90 -90 -20 -20 -100
我意识到示例输出是在一个只有一条记录的集合上......所以要显示另一条记录,另外还要说明如何轻松访问它:
> out_split$`037833100`$data_subset$Profit
[1] -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12
[41] 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20 -18 -6 5 -15 12 1 -20
clean_data <- stringi::stri_split_lines('
CUSIP BuyDate SellDate BuyAmount SellAmount Profit DaysHolding Over365Days
037833100 12/1/2015 3/1/2017 45 27 -18 456 1
17275R102 1/28/2016 2/21/2017 28 25 -3 390 1
38259P508 10/29/2015 2/18/2017 39 36 -3 478 1
594918104 3/1/2016 3/2/2017 35 40 5 366 1
68389X105 4/14/2016 2/21/2017 47 37 -10 313 0
037833100 12/11/2015 2/19/2017 46 40 -6 436 1
17275R102 1/12/2016 2/24/2017 29 34 5 409 1
38259P508 12/22/2015 2/20/2017 46 39 -7 426 1
594918104 12/19/2015 2/22/2017 26 36 10 431 1
68389X105 2/13/2016 3/2/2017 33 34 1 383 1
037833100 12/9/2015 2/18/2017 32 37 5 437 1
17275R102 2/13/2016 2/27/2017 48 25 -23 380 1
38259P508 11/30/2015 2/23/2017 45 34 -11 451 1
594918104 11/14/2015 2/27/2017 47 28 -19 471 1
68389X105 2/10/2016 2/17/2017 39 38 -1 373 1
037833100 4/7/2016 3/5/2017 44 29 -15 332 0
17275R102 3/3/2016 2/19/2017 26 36 10 353 0
037833100 11/25/2015 2/17/2017 28 40 12 450 1
037833100 1/10/2016 3/6/2017 35 36 1 421 1
037833100 3/4/2016 2/22/2017 45 25 -20 355 0
38259P508 2/10/2016 3/7/2017 42 40 -2 391 1
38259P509 12/5/2015 2/25/2017 31 39 8 448 1
38259P510 4/7/2016 2/27/2017 27 34 7 326 0
38259P511 3/26/2016 2/17/2017 27 39 12 328 0
17275R102 2/11/2016 2/27/2017 29 39 10 382 1
17275R102 11/24/2015 2/18/2017 45 35 -10 452 1
38259P509 3/29/2016 3/7/2017 46 27 -19 343 0
38259P509 4/5/2016 2/23/2017 38 38 0 324 0
17275R102 2/13/2016 2/26/2017 35 31 -4 379 1
594918104 3/10/2016 3/4/2017 29 28 -1 359 0
17275R102 10/30/2015 2/23/2017 40 30 -10 482 1
17275R102 12/15/2015 3/2/2017 25 38 13 443 1
594918104 2/2/2016 2/22/2017 26 32 6 386 1
594918105 3/8/2016 2/20/2017 26 29 3 349 0
594918106 11/21/2015 3/6/2017 44 38 -6 471 1
594918107 3/21/2016 2/20/2017 48 39 -9 336 0
594918108 12/21/2015 3/5/2017 37 28 -9 440 1
594918109 1/16/2016 3/5/2017 35 33 -2 414 1
594918110 2/8/2016 3/2/2017 41 39 -2 388 1
', omit_empty = TRUE)[[1]] %>%
stringi::stri_split_regex("\\s+", simplify = TRUE) %>% (function(x){
col_names <- x[1,]
a_data <- data.frame(x[2:nrow(x),], stringsAsFactors = FALSE)
colnames(a_data) <- col_names
as.data.frame(Map(function(i){
.call_col <- sprintf("as.%s",readr::guess_parser(i))
do.call(.call_col, list(i))
}, a_data))
})
答案 1 :(得分:1)
此聚合是一个简单的单行,dplyr
(或data.table
) - (并且您完全不需要预先设定数据帧):
require(dplyr)
summaryresults <- mydata %>%
group_by(CUSIP) %>%
summarize(Profit = sum(Profit), Over365Days = sum(Over365Days)) %>%
ungroup()
# %>% arrange(CUSIP, Over365Days) # ...if you want the summary result ordered by those vars
dplyr
是plyr
的继承者,非常易于使用和直观,使用mutate
,summarize
,filter
,{{1}等动词},select
和其他人。请参阅简介或教程:https://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html