如何将for循环转换为在r中应用

李基朱

我有以下循环。我试图将其转换为使用apply函数而不是循环,但我不知道如何重写代码。

for (i in 1:dim(Y)[2]) {
     K = K_origin
     print(i)

     e = lmmlite::eigen_rotation(K, t(Y)[i,], use_cpp = T)
     VC = lmmlite::fitLMM(
       e$Kva,
       e$y,
       e$X,
       reml = T,
       use_cpp = T,
       tol = 1e-6,
       check_boundary = T
     )

     write.table(
       VC$sigmasq_g,
       "Vg_temp.txt",
       row.names = F,
       col.names = F,
       append = T,
       quote = F,
       sep = "\n"
     )
     write.table(
       VC$sigmasq_e,
       "Ve_temp.txt",
       row.names = F,
       col.names = F,
       append = T,
       quote = F,
       sep = "\n"
     )
}

我想要这样的结果

Vg                  Ve
1.15521325512487    0.755118863386436
0.579039221720728   1.21733212837417
0.372439354137817   0.296327744338075
0.0668396114713355  0.300417453013007
0.00771158861391208 0.100176380868691
0.210174870097273   0.141907482831872
甘布尔先生

R 的apply函数必须被表述为 1)要迭代的东西,以及 2)要应用于 (1) 中的每个元素的函数。

但!您是否会从将您的特定循环转换为应用程序中获得任何收益,这是值得怀疑的。如果你的循环很慢,我猜这是由于执行的操作,而不是“R 在循环上很慢”。如果 中只有 6 行Y,则将循环重新制定为应用程序将一无所获!

对于您的循环,每个i都是独立的(与循环相反i,当结果取决于对 的计算时i-1)。因此,这使得重新制定配方变得非常容易。一般来说,

for (i in some_sequence) {
  do something with i
}

可以重新表述为

my_do_something <- function(i) {
  do something
}

for (i in some_sequence) {
  my_do_something(i)
}

可以再次直接重新表述为

sapply(some_sequence, my_do_something)

在你的情况下,这将是

my_rotate <- function(i) {
  e = lmmlite::eigen_rotation(K, t(Y)[i,], use_cpp = T)
  VC = lmmlite::fitLMM( ... )
  write.table(...)
  write.table(...)
  NULL
}

sapply(seq_len(dim(Y)[2]), my_rotate)

注意我是如何NULL在函数底部添加的那是因为apply将从迭代函数中收集返回值;write.table返回写入的数据不可见。尝试没有最后一个的函数NULL,看看apply返回什么

但是等等,还有更多!

由于您正在迭代特定的行(并特别询问apply),让我们放弃这些i东西并将该行提供给函数:

my_rotate_row <- function(x) {
  # you might or might not need to either use x as is, transpose it as t(x) or double transpose it, t(t(x)), to get the correct orientation. 
  # x is most likely an atomic vector, whereas `eigen_rotation` might be requiring either a row-vector or a column vector.

  e = lmmlite::eigen_rotation(K, x, use_cpp = T)
  VC = lmmlite::fitLMM( ... )
  # lets collect data directly into a data.frame or matrix, instead of using files:
  c(VC$sigmasq_g, VC$sigmasq_e)
}

现在您可以使用apply

apply(Y, 2, my_rotate_row)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章