我试图编写一个循环来迭代我的双精度矢量,并计算每组5个值的标准差。下面是我为此编写的代码,但是,当我尝试运行它时,它会将我的大部分NA作为一个值给出,这是不准确的。
数据是具有53412个元素的大矩阵,应该是大约1175行。
for(i in floor((nrow(data)/5)-5)){sd5[i] <-sd(data[seq((5*i) + 1,(5*i) + 5),6])}
我试图手动迭代它,只是在控制台中执行以下操作
sd(data[seq((5) + 1,(5*i) + 5),6])
sd(data[seq((10) + 1,(10) + 5),6])
sd(data[seq((15) + 1,(15) + 5),6])
每个都正常运行,但是,当我尝试使用循环时,它会导致大部分数据的NA,包括上面代码块中的第2行和第3行。
以下是正在阅读的CSV中的几行
2016-04-01,108.779999,110.00,108.199997,109.989998,25626200,109.989998
2016-03-31,109.720001,109.900002,108.879997,108.989998,25685700,108.989998
2016-03-30,108.650002,110.419998,108.599998,109.559998,45159900,109.559998
2016-03-29,104.889999,107.790001,104.879997,107.68,30774100,107.68
2016-03-28,106.00,106.190002,105.059998,105.190002,19303600,105.190002
为了以防万一,我想指出我从CSV文件中获取正确的值,至少在我手动执行sd()时,因为我已经将控制台输出与CSV文件进行了比较。但是,这并不意味着我没有以一种我似乎无法找到的方式错误地迭代。我将循环设置为向下舍入以避免任何越界错误。
答案 0 :(得分:1)
无需for
循环。
如果向量存储为x
,您可以执行以下操作:
NN <- length(x)
x <- x[1:(5*floor(length(x)/5))]
dim(x) <- c(5, length(x)/5)
apply(x, 2, sd)
如果它在data.frame
中,我会data.table
使用sd
,尤其是GForce
library(data.table); setDT(data)
data[ , sd(x), by = .(grp = (0:(length(x) - 1) %/% 5))]
- 在current devel version中进行了优化}):
{{1}}
答案 1 :(得分:1)
您可以重新转换为5列(或行)矩阵并获取行(或列)的FUN
由于矩阵太大,您可以使用matrixStats
库
mm <- read.csv(header = FALSE, text = "2016-04-01,108.779999,110.00,108.199997,109.989998,25626200,109.989998
2016-03-31,109.720001,109.900002,108.879997,108.989998,25685700,108.989998
2016-03-30,108.650002,110.419998,108.599998,109.559998,45159900,109.559998
2016-03-29,104.889999,107.790001,104.879997,107.68,30774100,107.68
2016-03-28,106.00,106.190002,105.059998,105.190002,19303600,105.190002")
set.seed(1)
mm <- mm[, -1]
mm <- matrix(sample(unlist(mm), 1500 * 55000, TRUE), 1500)
# num [1:1500, 1:55000] 110 109 110 110 110 ...
m2 <- matrix(mm, ncol = 5, byrow = TRUE)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 110.42 108.88 109.56 109.56 109.90
# [2,] 108.99 107.68 105.19 107.68 109.72
# [3,] 109.90 110.00 25626200.00 108.88 30774100.00
# [4,] 105.06 25685700.00 105.19 108.88 30774100.00
# [5,] 107.68 109.90 105.19 104.89 107.79
# [6,] 108.88 108.78 108.88 108.99 108.20
system.time({
sds <- apply(m2, 1, sd)
})
# user system elapsed
## a damn long time
# Timing stopped at: 114.028 0.81 115.398
library('matrixStats')
system.time({
sds <- rowSds(m2)
})
# user system elapsed
# 0.347 0.051 0.402
head(sds)
# [1] 5.620328e-01 1.726982e+00 1.555266e+07 1.556640e+07 2.072692e+00 3.141340e-01