背景:
查看公司在市场资本化方面同步移动的次数,例如,对于公司A和公司B,他们一起移动3次,当公司A和B显示的值不同于NA时,我想将其分开(这里,10)。我使用了一个逻辑公式,当它们具有相同的字母时为TRUE,当它们没有相同的字母时为FALSE,当A或B中有一个NA值时为NA。
问题是:
我使用的代码适用于小型套装,最多50家公司,然后需要花费太多时间,我希望能够为100家公司提供服务。 324.000.000数据点
输入(小子集):Dataframe" dat"
CompA CompB CompC CompD
1 A F <NA> A
2 A F <NA> F
3 F E <NA> A
4 A A <NA> A
5 F A <NA> F
6 A D <NA> D
7 F F <NA> B
8 A A <NA> F
9 F E <NA> F
10 <NA> C <NA> A
11 E F <NA> E
使用的代码:
v <- NULL
i <- 1
j <- 1
for(i in 1:length(dat)-1){
j <- i+1
while(j <= length(dat)-1){
str(dat)
qone <- data.frame(qone =
(as.character(dat[,i+1])==as.character(dat[,j+1])))
count1 <- length(which(qone == TRUE))/(length(which(qone ==
TRUE))+length(which(qone == FALSE)))
v <- append(v, count1)
v <- data.frame(v)
j <- j+1
}}
最终输出:
x1 x2 x3 x4 x5 x6
1 0.3 NA 0.5 NA 0.27 NA
第二个最终输出: 1 Nb TRUE 2 Nb FALSE
x1 x2 x3 x4 x5 x6
1 3 0 5 0 3 0
2 7 0 6 0 8 0
答案 0 :(得分:1)
在R中使用循环通常效率低下。由于您在嵌套循环中增加了数据框,因此它会严重减慢速度
尝试以下方法:
.as-console-wrapper { top: 0; max-height: 100% !important; }
我尝试创建一个包含~200,000行和~80列的虚拟数据框并运行上面的代码,在普通笔记本电脑上花了近一分钟。
有关所用功能的更多信息:
第一个library(data.table)
#Create the dummy data
companyData <- fread("~/test_data.csv",sep = "\t",na.strings = "<NA>")
#Two apply function to cross-over other columns over each column
v <- lapply(companyData, function(leftcomp) {
lapply(companyData, function(rightcomp) {
mean(leftcomp == rightcomp, na.rm = T)
})})
#Unlist data to get n*n vector which has all the values
results <- unlist(v)
#Some logic to collect the required elements only.
l <- length(companyData)
a <- 1:(l*l)
b <- rep(seq(1,l*l,by = l+1),times = rep(l,times = l))
log_vec <- a > b
#
# > log_vec
# [1] FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
final_result <- results[log_vec]
# > final_result
# CompA.CompB CompA.CompC CompA.CompD CompB.CompC CompB.CompD CompC.CompD
# 0.3000000 NaN 0.5000000 NaN 0.2727273 NaN
占据lapply
的每一列,并传递给第二个companyData
。此列再次与lapply
的每列进行比较。
companyData
mean(leftcomp == rightcomp, na.rm = T)
在公司串联的地方给出了leftcomp == rightcomp
的逻辑向量。当任何列为TRUE
时,它会返回NA
。
现在,在忽略NA
之后,此逻辑向量的mean
将给出我们的比率。这是有效的,因为NA
基本上为1,而TRUE
在R中为0。
例如:
FALSE
>log_vec
[1] TRUE FALSE FALSE FALSE NA TRUE
返回2/5 = 0.4。
现在,您想要选择唯一的元素(CompA vs CompB但不是CompB vs CompA)。
为此,
如果mean(log_vec,na.rm = T)
是您正在查看的公司数量(例如,4),则l
会创建上述所有计算a <- 1:(l*l)
的索引。
lapply
> a
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
是一个向量,如下所示:
b
此向量的> b
[1] 1 1 1 1 6 6 6 6 11 11 11 11 16 16 16 16
log_vec <- a > b
> log_vec
[1] FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
表示您需要选择的元素。
希望,现在更清楚了。