【问题标题】:R: For loop to perform Tidal analysis with Harmonic ConstituentsR:使用谐波成分执行潮汐分析的 For 循环
【发布时间】:2014-11-28 22:47:26
【问题描述】:

**已编辑,我已经取得了进展,但我认为我最初的问题没有尽可能好地构建。

我是 R 和计算机编程的新手,我正在尝试编写我的第一个 for 循环。

我希望能够使用 NOAA 的谐波成分进行一些潮汐分析。

我的初始 data=data 如下所示:

Constituent #   Name    Amplitude      Phase      Speed        
1                M2      3.264         29.0       28.98 
2                S2      0.781         51.9       30.0  
3                N2      0.63          12.3       28.43 
4                K1      1.263        136.8       15.04 
5                M4      0.043        286.0       57.96 

波高等式是h(t)= Amplitude*cos(Speed*t-Phase),其中 t 是时间。

因此,我需要对每个成分(行)执行此计算,并按时间对每个成分的结果求和。

所以我的中间结果将是一个表格,其中 ncols=时间戳数和 nrow= 成分数。

                   T1                               T2                              T3...
data[1,3]*cos(data[1,4]*T1-data[1,3])    data[1,3]*cos(data[1,4]*T2-data[1,3])
data[2,3]*cos(data[2,4]*T1-data[2,3])    data[2,3]*cos(data[2,4]*T2-data[2,3])
                   .
                   .
                   .

data[n,3]*cos(data[n,4]*T1-data[n,3])    data[n,3]*cos(data[n,4]*T2-data[n,3])

使用此表,我可以对各列求和,以获得每个时间戳的潮高的最终答案。

为此,我尝试创建一个 for 循环。

   DF=NULL

for (i in 1:nrow(data)){
  DF<- matrix(c(DF, data[i,2]*cos(pi/180*(data[i,4]*Time[,]-data[i,3]))))

}

这会将所有结果返回一个向量。我不知道如何通过时间戳将它分成列。它只是遍历第一个成分的所有时间戳,然后是第二个,依此类推。所以对于我当前的站,我有 37 个成分和 100 个时间戳,所以我的矩阵 DF 是 1 列,3700 行。

我尝试使用适当数量的列和行设置矩阵 DF,但这会为所有行和列返回一个结果。我还尝试了一个带有时间的嵌套 if 语句,以及许多我不记得的其他事情。

***使用 Rusan 的方法并完成了我正在使用下面的脚本所做的事情。任何其他方法都值得赞赏。

Time<-matrix(seq(1,100,1))   #my time series
n<-hh3(Time)                 #Function outlined by Rusan below
b<- matrix(c(rep(Time[1,1]:Time[nrow(Time),1], nrow(wave_table))))    #A repeating list to bind with n
height<-matrix(colSums(dcast(data.frame(cbind(b,n)),Constituent~V1,value.var="V1.1")[,-1])) #The sums of all the constituents at each time stamp, the final height of the wave at each time

这让我可以总结每个时间戳的所有成分。高度=时间 t 所有成分的总和。所以对于我上面的例子height(t1)=M2(t1)+S2(t1)+N2(t1)+K1(t1)+M4(t1)

我的最终输出是单个向量高度的矩阵。我希望这可以创建一个淹没持续时间曲线。

【问题讨论】:

  • 只是对我指定的函数hh3的评论。这可能会或可能不会做你认为它在做的事情,我建议你检查一个小的手动案例。特别是,您需要检查当您传递hh3 一个向量/矩阵时,data.table 和函数方法正在为您的目的执行您希望它执行的操作。请注意,我只为标量 t 演示了它。 (对其他人)有帮助的是,如果您显示您期望的输出示例......以及您正在使用公式做什么。即,您是对成分或名称求和还是……两者都不是?谢谢
  • 我做了检查,这是我需要的。它比 for 循环简单得多,对于初学者来说也更容易理解。
  • 在您的真实数据中,您是否有多个成分?或多个名称..或两者兼而有之?我正在尝试确定您正在计算的数量(高度)是否报告为每个名称(M2、K1 等)或每个组成部分(1、2 等)或两者都不是:在末尾只有一个高度值你的计算器?在您的玩具数据中,组成列和名称列都包含唯一项。我可能误解了,成分可能只是“行号”而不是数据的一部分,等等。
  • 没错,多个成分的名称是行号,然后是成分名称。我相信它们是回归分析的一部分,因此每个成分都在波高中起作用。例如,M2 是主要的月球半日成分,我需要将特定时间的所有成分相加,以计算该特定时间的波浪高度。我刚刚开始为一个工作项目了解这些,但你可以找到如果您有兴趣,请访问 NOAA 网站link
  • 好的。这不是推荐的方法,但这样的工作是否可行:as.data.table(hh3(1:100))[,{sum(V1)},by=Name][,{sum(V1)}]?其中hh3hh3&lt;-function(t) wave_table[,{Amplitude*cos(Speed*t-Phase)}, by=Name]

标签: r loops for-loop apply


【解决方案1】:

也许这不是一个答案 - 但我会建议一种不同的方法。我将在 R 中使用包 data.table

library(data.table)

#use own location of your data
wave_table=fread(input="F:\\wave.csv");

wave_table
#           Constituent Name Amplitude Phase Speed
#    1:           1   M2     3.264  29.0 28.98
#    2:           2   S2     0.781  51.9 30.00
#    3:           3   N2     0.630  12.3 28.43
#    4:           4   K1     1.263 136.8 15.04
#    5:           5   M4     0.043 286.0 57.96

#create a function which does your calculation on the named columns of your data, 
#taking time 't' as a parameter

hh<-function(t){ wave_table[,{Amplitude*cos(Speed*t-Phase)}] }
hh2<-function(t) wave_table[,{Amplitude*cos(Speed*t-Phase)}, by=Name]
hh3<-function(t) wave_table[,{Amplitude*cos(Speed*t-Phase)}, by=Constituent]
hh4<-function(t) wave_table[,{sum(Amplitude*cos(Speed*t-Phase))}, by=Constituent]

#Now the function `hh` can be used like this, giving you a bit 
#more flexibility with what you want to do, perhaps?

hh(1)
#3.26334722 -0.77775795 -0.57472163 -0.91362687 -0.01165717

hh2(1)
#   Name          V1
#1:   M2  3.26334722
#2:   S2 -0.77775795
#3:   N2 -0.57472163
#4:   K1 -0.91362687
#5:   M4 -0.01165717

hh4(1) #after adding an extra row to your data: "Constituent=1, Name=M3, 
#Amp=1.263,Phase=51.9, Speed=15.04
#   Constituent          V1
#1:           1  4.10718774
#2:           2 -0.77775795
#3:           3 -0.57472163
#4:           4 -0.91362687
#5:           5 -0.01165717

一般而言,应避免 R 中针对此类问题的循环,因为它们很慢/有更好的工具可用。循环通常是“最后的手段”。

如果函数 hhhh4 不能完全满足您的要求,则可以使用其他变体。查看http://cran.r-project.org/web/packages/data.table/vignettes/datatable-faq.pdf

【讨论】:

  • 我使用了 Rusan 的方法,并完成了我在上面的问题中添加的内容。这可行,但如果有更好的方法,请发表评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多