2016-05-12 65 views
-1

我想弄明白如何使用data.tables。它进展不顺利。如何基于另一个data.table子集data.table?

我有一大堆data.table与返回和AUM。我将data.table分为两个data.tables,一个带有返回值,另一个带有AUM。我现在想要将收益数据表设置为子集,以获得AUM小于第50百分位的基金的回报。

为了给你一个想法,这是我的代码:

fundDetails <- data.table(read.table("Fund_Deets.csv", sep = ",", fill = TRUE, quote="\"", header=TRUE)) 
fundNAV <- data.table(read.table("NAV_AUM.csv", sep = ",", fill = TRUE, quote="\"", header=TRUE)) 

allFundDetails <- fundDetails[Currency == 'USD'] 
allFundNAV <- fundNAV[Fund.ID %in% allFundDetails$Fund.ID] 
allFundAUM <- allFundNAV[Type == 'AUM', -c(1,3), with = FALSE] 
allFundAUM <- setnames(data.table(t(sapply(allFundAUM[,-1, with = FALSE],as.numeric))), as.character(allFundAUM$Fund.ID)) 
allFundReturns <- allFundNAV[Type == 'Return', -c(1,3), with = FALSE] 
allFundReturns <- setnames(data.table(t(sapply(allFundReturns[,-1, with = FALSE],as.numeric)/100)), as.character(allFundReturns$Fund.ID)) 
smallFundReturns <- data.table(sapply(allFundReturns, function(x) rep(NA, length(x)))) 

这将产生以下三个表(smallFundReturns显然只是NA的):

> allFundAUM[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA NA NA  1 27 
    2: NA NA NA NA NA NA 117 NA  1 27 
    3: NA NA NA NA NA NA 120 NA  1 27 
    4: NA NA NA NA NA NA 133 NA  1 27 
    5: NA NA NA NA NA NA 146 NA  1 29 
---               
260: NA NA NA NA NA NA NA NA NA NA 
261: NA NA NA NA NA NA NA NA NA NA 
262: NA NA NA NA NA NA NA NA NA NA 
263: NA NA NA NA NA NA NA NA NA NA 
264: NA NA NA NA NA NA NA NA NA NA 
> allFundReturns[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA  NA NA 0.0188 -0.0116 
    2: NA NA NA NA NA NA -0.0315 NA -0.0120 0.0134 
    3: NA NA NA NA NA NA -0.0978 NA -0.0908 -0.0206 
    4: NA NA NA NA NA NA -0.0445 NA -0.0269 -0.0287 
    5: NA NA NA NA NA NA 0.0139 NA 0.0298 -0.0141 
---                 
260: NA NA NA NA NA NA  NA NA  NA  NA 
261: NA NA NA NA NA NA  NA NA  NA  NA 
262: NA NA NA NA NA NA  NA NA  NA  NA 
263: NA NA NA NA NA NA  NA NA  NA  NA 
264: NA NA NA NA NA NA  NA NA  NA  NA 
> smallFundReturns[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA NA NA NA NA 
    2: NA NA NA NA NA NA NA NA NA NA 
    3: NA NA NA NA NA NA NA NA NA NA 
    4: NA NA NA NA NA NA NA NA NA NA 
    5: NA NA NA NA NA NA NA NA NA NA 
---               
260: NA NA NA NA NA NA NA NA NA NA 
261: NA NA NA NA NA NA NA NA NA NA 
262: NA NA NA NA NA NA NA NA NA NA 
263: NA NA NA NA NA NA NA NA NA NA 
264: NA NA NA NA NA NA NA NA NA NA 

for (i in 1:nrow(allFundReturns)){ 
    theSubset <- as.vector(allFundReturns[i,] <= as.numeric(quantile(allFundAUM[i,], .5, na.rm = TRUE))) 
    theSubset[is.na(theSubset)] <- FALSE 
    theSubset <- colnames(allFundReturns)[theSubset] 
    smallFundReturns[i,theSubset, with = FALSE] = allFundReturns[i,theSubset, with = FALSE] 
} 

我想以此来子集for循环(使用for循环尝试调试):

for (i in 1:nrow(allFundReturns)){ 
    theSubset <- as.vector(allFundReturns[i,] <= as.numeric(quantile(allFundAUM[i,], .5, na.rm = TRUE))) 
    theSubset[is.na(theSubset)] <- FALSE 
    theSubset <- colnames(allFundReturns)[theSubset] 
    smallFundReturns[i,theSubset, with = FALSE] = allFundReturns[i,theSubset, with = FALSE] 
} 

这会产生一个错误:

Error in `[<-.data.table`(`*tmp*`, i, theSubset, with = FALSE, value = list(: 
    unused argument (with = FALSE) 

我试图消除“与”一部分,但这吐出一堆警告:

> warnings() 
Warning messages: 
1: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '41526' (3019 unused) 
2: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '45993' (3019 unused) 
3: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '45994' (3019 unused) 
4: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 

我是如何做到这一点困惑。关于如何在第一个子集上对第二个data.table进行子集化的任何想法?

编辑:

我尝试下面的建议:

smallFundReturns[i,(theSubset):=allFundReturns[i,(theSubset), with = FALSE], with = FALSE] 

而且我得到了这些警告():

> warnings() 
Warning messages: 
1: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 
    Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column to 'double' first (by creating a new 'double' vector length 264 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please. 
2: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 
    Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column to 'double' first (by creating a new 'double' vector length 264 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please. 
3: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 

并制作这个代码,以 'TRUE' 我到处会期望一个数字:

> smallFundReturns[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA NA NA TRUE TRUE 
    2: NA NA NA NA NA NA NA NA NA NA 
    3: NA NA NA NA NA NA NA NA NA NA 
    4: NA NA NA NA NA NA NA NA NA NA 
    5: NA NA NA NA NA NA NA NA NA NA 
---               
260: NA NA NA NA NA NA NA NA NA NA 
261: NA NA NA NA NA NA NA NA NA NA 
262: NA NA NA NA NA NA NA NA NA NA 
263: NA NA NA NA NA NA NA NA NA NA 
264: NA NA NA NA NA NA NA NA NA NA 

编辑2:

我想出了这个问题。显然,这一行:

smallFundReturns <- data.table(sapply(allFundReturns, function(x) rep(NA, length(x)))) 

创建表为逻辑。我将其更改为以下行:

smallFundReturns <- data.table(sapply(allFundReturns, function(x) as.numeric(rep(NA, length(x))))) 

而且@HubertL修复后一切正常。谢谢!!

回答

1

你必须把它写这样的:改善

smallFundReturns[i,(theSubset):=allFundReturns[i,(theSubset), with = FALSE], with = FALSE] 
+0

这使得'真',我期望的数字。我非常感谢这个帮助,但是你能否通过应该做的事情走过,所以我可以找出为什么'TRUE'出现而不是我期待的回报? – lukehawk

+0

我想通了。谢谢! – lukehawk

+0

很确定外面的'with = F'是不必要的 – eddi

1

建议:

用fread代替如果函数read.table可能尝试读取数据。它速度更快,结果是data.table而不是data.frame。

使用语句“with = FALSE”进行“data.table操作”时,实际上会强制R使用慢得多的data.frame操作,而不是使用快速的data.table方法。

玩得开心

+0

谢谢!我不知道有一个阅读功能。另外,你知道我会如何达到相同的结果,而不使用? (我没有试图听起来粗鲁,我仍然在学习data.table包。)还是有更好的方法一次完成,而不使用循环或应用函数?要获得每列只有第25个百分点和更差的值? – lukehawk