使用列表评估一个变量

时间:2014-04-06 05:58:04

标签: r math numerical-methods

我有以下代码:

nth <- expression(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p)))
  nth <- as.expression(gsub('pi',pi,nth))  
  nth <- as.expression(gsub('p',p,nth))
  nth <- as.expression(gsub('a0',a0,nth))
  nth <- as.expression(gsub('a',a,nth))
  nth <- as.expression(gsub('b',b,nth))

这导致表达式:

"((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(i * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * sin(i * 3.14159265358979 * x/1))"

接下来我要做的是用一个列表(例如i = 1:3)来评估i而不评估x。所以我想要得到的是:

 "((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(1 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * cos(2 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * cos(3 * 3.14159265358979 * x/1))) + sum(((1/1) * 0.251688909862584 * sin(1 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * sin(2 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * sin(3 * 3.14159265358979 * x/1)))"

我该怎么做?感谢。

3 个答案:

答案 0 :(得分:1)

为什么不尝试这个。您将看到我在循环中包装了您需要的值,并将所有输出放在一个新的“已完成”数据框中,该数据框将在您循环循环时更新。您可以指定我有多少,并根据需要更改表达式:

# Define the initial variables that might be changed here
var_1 <- 3.14159265358979 # This referred to pi in your initial expression
var_2 <- 1 # This referred to p in your initial expression
var_3 <- 1.26424111790395 # This refers to a0 in your initial expression
var_4 <- 0.251688909862584 # This refers to a in your initial expression
var_5 <- -1.03501509824516e-16 # This refers to b in your initial expression

n <- 3 # This is the number of equations that will be run through

# Create an empty dataframe to hold the outputted expressions
finished = c() # Empty data frame

# Create an array holding values from 1 to the number of n's that will be run through
cycle <- c(1:n)

# Convert cycle to a matrix
cycle <- as.matrix(cycle)

# The variable we will be changing is i ... Create the initial loop
for (i in 1:3 ) {
  nth <- expression(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p))) # Write the expression to be changed

  # Substitute in all the relevant values. Note that this is made to be more explicity
  nth <- as.expression(gsub('pi',var_1,nth))  
  nth <- as.expression(gsub('p',var_2,nth))
  nth <- as.expression(gsub('a0',var_3,nth))
  nth <- as.expression(gsub('a',var_4,nth))
  nth <- as.expression(gsub('b',var_5,nth))

  # I will also, for each value, substitue in relevant value from the cycle array
  # This will change the i values for you
  i_index <- cycle[i,1]
  i_index <- as.character(i_index)

  nth <- as.expression(gsub('i',i_index,nth)) # Append the nth equation

  # I will then bind this solution into the finished data frame to hold all solutions
  finished[i] = nth
}

这是运行代码后生成的输出:

expression("((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(1 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s1n(1 * 3.14159265358979 * x/1))", 
    "((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(2 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s2n(2 * 3.14159265358979 * x/1))", 
    "((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(3 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s3n(3 * 3.14159265358979 * x/1))")

答案 1 :(得分:0)

这应该让你去。你肯定在gsub的正确轨道上 请注意,原始表达式中的j分别被替换为1,2和3。我选择了j,因为gsub i会干扰sinpi。希望它有所帮助...

> expres <- "(((1/p)*a0/2)+sum(((1/p)*a*cos(j*pi*x/p)))+sum((1/p)*b*sin(j*pi*x/p)))"
> noquote(sapply(1:3, function(j){
      GS <- gsub("j", as.numeric(j), expres)
      paste0("expression(", GS, ")")
  }))
[1] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(1*pi*x/p)))+sum((1/p)*b*sin(1*pi*x/p))))
[2] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(2*pi*x/p)))+sum((1/p)*b*sin(2*pi*x/p))))
[3] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(3*pi*x/p)))+sum((1/p)*b*sin(3*pi*x/p))))

答案 2 :(得分:0)

另一种可能的解决方案是使用substitute

g = function(i){
    env = list(pi=pi, p=1, a0=1.26424111790395, a=0.251688909862584, b=-1.03501509824516e-16, i=i)
    as.character(as.expression(substitute(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p)), env)))
}
paste(lapply(1:3, g), collapse=", ")