Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 在R中没有for循环的行之间移动值_Performance_R_For Loop_Dataframe - Fatal编程技术网

Performance 在R中没有for循环的行之间移动值

Performance 在R中没有for循环的行之间移动值,performance,r,for-loop,dataframe,Performance,R,For Loop,Dataframe,我已经编写了一些用于组织以不同频率采样的数据的代码,但是我大量使用了for循环,当数据集很大时,这会显著降低代码的运行速度。我一直在研究我的代码,想办法删除for循环以加快速度,但其中一个循环让我难倒了 举个例子,假设数据是在3Hz下采样的,所以我每秒得到三行数据。但是,变量A、B和C都是以1Hz的频率采样的,因此我将每三行为它们中的每一行获取一个值。变量在一秒钟内连续采样,从而形成数据的对角线性质 使事情更加复杂的是,有时原始数据集中会丢失一行 我的目标是:确定了我希望保留的行之后,我希望将非

我已经编写了一些用于组织以不同频率采样的数据的代码,但是我大量使用了for循环,当数据集很大时,这会显著降低代码的运行速度。我一直在研究我的代码,想办法删除for循环以加快速度,但其中一个循环让我难倒了

举个例子,假设数据是在3Hz下采样的,所以我每秒得到三行数据。但是,变量A、B和C都是以1Hz的频率采样的,因此我将每三行为它们中的每一行获取一个值。变量在一秒钟内连续采样,从而形成数据的对角线性质

使事情更加复杂的是,有时原始数据集中会丢失一行

我的目标是:确定了我希望保留的行之后,我希望将非NA值从后续行向上移动到keeper行中。如果不是因为数据丢失问题,我将始终保留包含第一个变量值的行,但如果其中一行丢失,我将保留下一行

在下面的示例中,第六个样本和第十个样本丢失

A <- c(1, NA, NA, 4, NA, 7, NA, NA, NA, NA)
B <- c(NA, 2, NA, NA, 5, NA, 8, NA, 11, NA)
C <- c(NA, NA, 3, NA, NA, NA, NA, 9, NA, 12)

test_df <- data.frame(A = A, B = B, C = C)

test_df
     A  B  C
 1   1 NA NA
 2  NA  2 NA
 3  NA NA  3
 4   4 NA NA
 5  NA  5 NA
 6   7 NA NA
 7  NA  8 NA
 8  NA NA  9
 9  NA 11 NA
10  NA NA 12

keep_rows <- c(1, 4, 6, 9)
A这应该可以做到:

test_df = with(test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]))
test_df = data.frame(test_df[!apply(test_df, 1, function(x) all(is.na(x))), ])
colnames(test_df) = c('A', 'B', 'C')
>测试
A、B、C
1  1  2  3
2 4 5 NA
3  7  8  9
4 NA 11 12
如果你想要更快的东西:


所以你的问题只是关于没有循环地向上移动。显然你已经解决了第一步

> test_m <- with( test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]) )
> test_m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]   NA   NA   NA
[3,]   NA   NA   NA
[4,]    4    5   NA
[5,]   NA   NA   NA
[6,]    7    8    9
[7,]   NA   NA   NA
[8,]   NA   11   12
>测试
[,1] [,2] [,3]
[1,]    1    2    3
[2,]NA-NA
[3,]NA-NA-NA
[4,]4 5 NA
[5,]NA-NA-NA
[6,]    7    8    9
[7,]NA-NA-NA
[8,]NA 11 12
它现在是一个矩阵。在没有循环的情况下,您可以轻松地消除现在没有数据点的行。如果要将其返回到data.frame,则可以使用其他方法,但此方法对于大量数据运行速度最快。我只想让NA成为一个不可能的值。。。也许是-1,但您将最了解您的数据。。。也许是-pi

test_m[is.na(test_m)] <- -1

test_m[is.na(test_m)]在@John Colby的伟大答案的基础上,我们可以摆脱apply步骤,并将其加快一点(大约20倍):

再次编辑…而且@John Colby的更新答案更快

# John Colby's method, 0.39 secs
system.time({
  df4 = with(test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]))
  df4 = data.frame(df4[rowSums(is.na(df4)) != ncol(df4), ])
  colnames(df4) = c('A', 'B', 'C')
})

identical(df1, df4) # TRUE

循环不是
,但它仍然是一个循环。请参见编辑。它总是一个循环,但至少这个循环都是C代码。它不是“总是”一个循环。我肯定有一个矢量化的解决方案。如果今晚没人能比得上我,我就把它写下来。@goodside好极了,我想知道有没有。上面的第二种方法在我的机器上10^6行只需要50毫秒,但您可以将其与您在您的机器上所做的进行比较。谢谢您,John。这个解决方案适合我!我需要更加熟悉“with”和“apply”函数,这样我才能自己想出这种类型的答案?如果,比方说,您没有删除6和10,而是删除了4、5和6,您将如何检测到发生了这种情况?是的,可能会丢失多个连续的行。在代码中的其他地方考虑了这些因素之后,我已经确定了要保留哪些行,并且我最终会得到类似于我在示例中给出的“rows\u to\u keep”变量的东西,该变量是由代码生成的,而不是用户定义的。我不确定这是否会在给出的解决方案中引起问题,因为“rows\u to\u keep”变量没有实现。谢谢你,John。你在这里建议的搬进搬出NA的方法将来肯定会对我有用。我不知道system.time函数,但我会从中得到很多好处!谢谢你的建议和方法。
test_m[is.na(test_m)] <- -1
test_m <- test_m[rowSums(test_m) > -3,]
test_m[test_m == -1] <- NA
test_m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5   NA
[3,]    7    8    9
[4,]   NA   11   12
# Create a bigger test set 
A <- c(1, NA, NA, 4, NA, 7, NA, NA, NA, NA)
B <- c(NA, 2, NA, NA, 5, NA, 8, NA, 11, NA)
C <- c(NA, NA, 3, NA, NA, NA, NA, 9, NA, 12)
n=1e6; test_df = data.frame(A=rep(A, len=n), B=rep(B, len=n), C=rep(C, len=n))

# John Colby's method, 9.66 secs
system.time({
  df1 = with(test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]))
  df1 = data.frame(df1[!apply(df1, 1, function(x) all(is.na(x))), ])
  colnames(df1) = c('A', 'B', 'C')
})

# My method, 0.48 secs
system.time({
  df2 = with(test_df, data.frame(A=A[1:(length(A)-2)], B=B[2:(length(B)-1)], C=C[3:length(C)]))
  df2 = df2[is.finite(with(df2, A|B|C)),]
  row.names(df2) <- NULL
})

identical(df1, df2) # TRUE
# John's method, 0.50 secs
system.time({
  test_m = with(test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]))
  test_m[is.na(test_m)] <- -1
  test_m <- test_m[rowSums(test_m) > -3,]
  test_m[test_m == -1] <- NA
  df3 <- data.frame(test_m)
  colnames(df3) = c('A', 'B', 'C')
})

identical(df1, df3) # TRUE
# John Colby's method, 0.39 secs
system.time({
  df4 = with(test_df, cbind(A[1:(length(A)-2)], B[2:(length(B)-1)], C[3:length(C)]))
  df4 = data.frame(df4[rowSums(is.na(df4)) != ncol(df4), ])
  colnames(df4) = c('A', 'B', 'C')
})

identical(df1, df4) # TRUE