在R中填充数据帧时避免循环

在R中填充数据帧时避免循环,r,for-loop,dataframe,vectorization,populate,R,For Loop,Dataframe,Vectorization,Populate,我有一个空的数据框,有2784列和150行 T_modelled <- data.frame(matrix(ncol = 2784, nrow = 150)) names(T_modelled) <- paste0("t=", t_sec_ERT) rownames(T_modelled) <- paste0("z=", seq(from = 0.1, to = 15, by = 0.1)) 在哪里 MANSRT我相信就是这样。 创建T_modeled后立即运行第一条指令,需

我有一个空的数据框,有2784列和150行

T_modelled <- data.frame(matrix(ncol = 2784, nrow = 150))
names(T_modelled) <- paste0("t=", t_sec_ERT)
rownames(T_modelled) <- paste0("z=", seq(from = 0.1, to = 15, by = 0.1))
在哪里


MANSRT我相信就是这样。
创建
T_modeled
后立即运行第一条指令,需要测试结果是否相等

Tm <- T_modelled

Tm我更愿意将数据放在长格式中,将
z
t_secu_ERT
的所有组合作为两列,以便利用矢量化。虽然我通常更喜欢在长格式和宽格式之间切换
tidyr
,但我已尝试将此作为基本解决方案:

t_sec_ERT <- seq(from = -23349600, to = 6706800, by = 10800)
z <- seq(from = 0.1, to = 15, by = 0.1)

v <- expand.grid(t_sec_ERT, z) 
names(v) <- c("t_sec_ERT", "z")
v$z_tmp <- v$z-0.1
v$T_tmp <- MANSRT+As*e^(-v$z_tmp*(omega/(2*K))^0.5)*sin(omega*v$t_sec_ERT-((omega/(2*K))^0.5)*v$z_tmp)

T_modelled <- data.frame(matrix(v$T_tmp, nrow = length(z), ncol = length(t_sec_ERT), byrow = TRUE))
names(T_modelled) <- paste0("t=", t_sec_ERT)
rownames(T_modelled) <- paste0("z=", seq(from = 0.1, to = 15, by = 0.1))

t_secu_ERTRui当然是正确的,我只想在编写这样的循环时提出一种推理方法

有两个数值向量。R中的数字函数通常是矢量化的。我的意思是你可以做这样的事情

x <- c(1, 6, 3)
sum(x)
x_ <- 0
for (i in x) {
    x_ <- i + x_ 
}
x_
看起来不错。然后开始在
t\u sec\u ERT
的元素上循环

z_tmp <- z - 0.1
i <- 1

T_tmp <- MANSRT + As * 
         exp(-z_tmp*(omega/(2*K))^0.5) * 
         sin(omega*t_sec_ERT[i] - ((omega/(2*K))^0.5)*z_tmp)
T_tmp <- matrix(nrow=length(z), ncol=length(t_sec_ERT))

for (i in 1:length(t_sec_ERT)) {
    T_tmp[, i] <- MANSRT + As * 
             exp(-z_tmp*(omega/(2*K))^0.5) * 
             sin(omega*t_sec_ERT[i] - ((omega/(2*K))^0.5)*z_tmp)
}

<> P>就像你以前接受过的问题,简单地考虑使用<代码> Spest,重复向量,TySeCixErt,它与你想要的数据文件的列数一样长。但首先将z的每个元素调整0.1。另外,不需要事先创建空数据帧

z_adj <- z - 0.1

T_modelled2 <- data.frame(sapply(t_sec_ERT, function(ert)
        MANSRT+As*e^(-z_adj*(omega/(2*K))^0.5)*sin(omega*ert-((omega/(2*K))^0.5)*z_adj)))

colnames(T_modelled2) <- paste0("t=", t_sec_ERT)
rownames(T_modelled2) <- paste0("z=", z)

all.equal(T_modelled, T_modelled2)
# [1] TRUE

z_adj.你不是刚问了一个有公认答案的问题吗?为什么要回到嵌套的
for
循环?自从大约两个月前我开始学习R以来,我一直在大量使用循环。就像类似的问题一样,这个循环已经存在了一段时间,而不是在看到我上一个问题的解决方案后再写。就在最近,我看到越来越多的博客和评论建议在R中执行任务时避免循环。这就是为什么我试图做出改变,但例如
sapply
对我来说仍然不像循环那样“自然”。然而,我开始对它产生兴趣,我相信我现在通过对sapply的函数调用得到了解决方案。是的,效果很好。我认为,如果您事先存储函数,则更容易阅读,因此只需将其调用到
sapply
。但这可能只是口味的问题。在函数之前定义z_adj也是有意义的。事实上,你可以这样做。这里我们在
sapply
中使用了一个匿名函数,这使得循环更加一致。我仍然希望sapply的选项能够利用R的矢量化方式执行任务。请注意:包括
sapply
在内的apply函数系列只是隐藏在下面的循环,而不是矢量化的。读这个。通常是一种误解,但R中的
for
循环没有什么错。您的问题是每次更新每一行和每一列(即单元格)时都会嵌套循环,所以150x2784次迭代!在这里和使用
sapply
时,每次迭代都会处理一整列,因此只有150个。将函数存储在
f
中,然后调用它到
sapply
的解决方案很好!如果您设置了
data.frame(sapply(t_sec_ERT,f))
,则最初将其存储为数据帧。
x_ <- 0
for (i in x) {
    x_ <- i + x_ 
}
x_
z_tmp <- z - 0.1
i <- 1

T_tmp <- MANSRT + As * 
         exp(-z_tmp*(omega/(2*K))^0.5) * 
         sin(omega*t_sec_ERT[i] - ((omega/(2*K))^0.5)*z_tmp)
T_tmp <- matrix(nrow=length(z), ncol=length(t_sec_ERT))

for (i in 1:length(t_sec_ERT)) {
    T_tmp[, i] <- MANSRT + As * 
             exp(-z_tmp*(omega/(2*K))^0.5) * 
             sin(omega*t_sec_ERT[i] - ((omega/(2*K))^0.5)*z_tmp)
}
f <- function(x) {
    MANSRT + As * 
    exp(-z_tmp*(omega/(2*K))^0.5) * 
    sin(omega*x - ((omega/(2*K))^0.5)*z_tmp)
}

T_tmp <- sapply(t_sec_ERT, f)
z_adj <- z - 0.1

T_modelled2 <- data.frame(sapply(t_sec_ERT, function(ert)
        MANSRT+As*e^(-z_adj*(omega/(2*K))^0.5)*sin(omega*ert-((omega/(2*K))^0.5)*z_adj)))

colnames(T_modelled2) <- paste0("t=", t_sec_ERT)
rownames(T_modelled2) <- paste0("z=", z)

all.equal(T_modelled, T_modelled2)
# [1] TRUE