![](/img/trans.png)
[英]Converting for() loops to apply() functions in R for a custom XIRR function
[英]Converting R loops to functional form with apply
我編寫了一些R代碼來解析字符串,計算子字符串的出現次數,然后填充一個子字符串計數表。 它運行正常,但它對我正在使用的實際數據(這是非常大的)真的很慢,而且我知道很多是因為我使用循環而不是apply系列中的函數。 我一直在嘗試將此代碼轉換為功能形式,我沒有運氣,任何人都可以幫忙嗎? 我最大的問題是我無法找到一種方法來使用列名來匹配apply結構中的值。 這是包含一些玩具數據的代碼:
#Create toy data, list of unique substrings
code_frame<-matrix(c(c('a|a|b|c|d'),c('a|b|b|c|c'),c('a|b|c|d|d')),nrow=3,ncol=1)
all_codes_list<-c('a','b','c','d')
#create data frame with a column for each code and a row for each job
code_count<-as.data.frame(matrix(0, ncol = length(all_codes_list), nrow = nrow(code_frame)))
colnames(code_count)<-all_codes_list
#fill in the code_count data frame with entries where codes occur
for(i in 1:nrow(code_frame)){
test_string<-strsplit(code_frame[i,1],split="|",fixed=TRUE)[[1]]
for(j in test_string){
for(g in 1:ncol(code_count)){
if(j == all_codes_list[g]){
code_count[i,g]<-code_count[i,g]+1
}
}
}
}
謝謝。
一個oneliner,分為3行:
do.call(rbind,
lapply(strsplit(code_frame[,1], "|", fixed=TRUE),
function(x) table(factor(x, levels=all_codes_list))))
請注意, strsplit
是矢量化的,因此您不需要在所有行上使用外部循環。 你的內部循環基本上是在計算每個代碼的出現次數,這是一個table
的應用程序。 最后, do.call(rbind, *)
是將行列表轉換為單個數據幀的標准習慣用法。
qdap軟件包有一個非常適合這個的工具,應該非常快速且編碼很少,稱為mtabulate
:
library(qdap)
mtabulate(strsplit(code_frame, "\\|"))
## a b c d
## 1 2 1 1 1
## 2 1 2 2 0
## 3 1 1 1 2
基本上它需要矢量列表(來自strsplit
輸出)並為每個矢量創建一行表格信息。
編輯:如果速度真的是你的事情在這里是1000復制的基准(Win 7機器上的microbenchmark包 ):
Unit: microseconds
expr min lq median uq max neval
HONG() 592.458 620.448 632.111 644.706 4650.560 1000
TYLER() 324.220 342.413 351.743 361.073 3556.613 1000
HENRIK() 1527.329 1560.450 1578.177 1614.331 4828.297 1000
和視覺輸出:
base
替代方案:
df <- read.table(text = code_frame, sep = "|")
tt <- apply(df, 1, function(x){
x2 <- factor(x, levels = letters[1:4])
table(x2)
})
t(tt)
# a b c d
# [1,] 2 1 1 1
# [2,] 1 2 2 0
# [3,] 1 1 1 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.