循环在R中花费太多时间?
背景: 求出公司市值同步变动的次数,例如A公司和B公司,它们一起变动3次,我想在A公司和B公司显示的值不同于NA时将其除以(这里,10)。我使用了一个逻辑公式,当它们有相同的字母时为TRUE,当它们没有相同的字母时为FALSE,当a或B中有一个NA值时为NA 问题是: 我使用的代码适用于小型集合,最多50家公司,然后需要花费太多时间,我希望对100家公司的集合执行此操作。324.000.000数据点 输入(小子集):数据帧“dat” 第二次最终输出:1 Nb真2 Nb假循环在R中花费太多时间?,r,R,背景: 求出公司市值同步变动的次数,例如A公司和B公司,它们一起变动3次,我想在A公司和B公司显示的值不同于NA时将其除以(这里,10)。我使用了一个逻辑公式,当它们有相同的字母时为TRUE,当它们没有相同的字母时为FALSE,当a或B中有一个NA值时为NA 问题是: 我使用的代码适用于小型集合,最多50家公司,然后需要花费太多时间,我希望对100家公司的集合执行此操作。324.000.000数据点 输入(小子集):数据帧“dat” 第二次最终输出:1 Nb真2 Nb假 x1
x1 x2 x3 x4 x5 x6
1 3 0 5 0 3 0
2 7 0 6 0 8 0
在R中使用循环通常效率低下。由于您正在嵌套循环中增加数据帧,因此会大大降低速度 尝试以下方法:
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
mean(log\u vec,na.rm=T)
返回2/5=0.4
现在,您想要选择唯一的元素(CompA与CompB,但不是CompB与CompA)
为此,
如果l
是您正在查看的公司数量(例如4家),a b
[1] 1 1 1 1 6 6 6 6 11 11 11 11 16 16 16 16
日志向量b
>对数向量
[1] 假真假假真假假假假假假假假假假假假假
对于需要拾取的元素,此向量具有TRUE
希望,现在更清楚了。您正在循环中增长对象,这导致了问题。查看这些链接了解更多信息:&谢谢,我将在这里@tung查看一些加快速度的内容;董的评论很好,但也看到了:也看到了:还有,你的样本结果中
x5
的值不应该是0.2727吗?非常感谢@戴夫!是的,我在问题中得到了错误的数据对不起。。我得到这个错误:Ops.factor中的错误(leftcomp,righcomp):因子的级别集不同,如果你不介意的话,我还有一个问题。。如果我想计算每家公司的正确和错误的数量,看看它们是否具有统计意义,我就用我想要的结果编辑了这个问题@DaveI将尝试在今天晚上的答案上添加更多细节。你能详细说明一下统计显著性问题吗?你的假设是什么?抱歉,我在问题或输出中没有看到任何编辑。抱歉,它没有更新。。通过统计意义,我的意思是只计算每个公司对的正确和错误的数量,例如,对于A和B公司,我们有3个正确和7个错误
x1 x2 x3 x4 x5 x6
1 0.3 NA 0.5 NA 0.27 NA
x1 x2 x3 x4 x5 x6
1 3 0 5 0 3 0
2 7 0 6 0 8 0
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
>log_vec
[1] TRUE FALSE FALSE FALSE NA TRUE
> a
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
> 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