简体   繁体   English

R嵌套for循环以编写多个函数并将其绘制

[英]R nested for loop to write multiple functions and plot them

Here is my data: 这是我的数据:

color   a   b
red     3   1.3
blue    9   1.8
purple  13  1.2
green   4   1.1
orange  7   0.9
yellow  6   2.1
brown   7   1.8

For each row, I'd like to write a function called "fun_color" by the following format: y = a*(x^b) 对于每一行,我想通过以下格式编写一个名为“ fun_color”的函数: y = a*(x^b)

(a and b are the values of the data$a and data$b column for each row. x is the domain of the function.) (a和b是每一行的data $ a和data $ b列的值。x是函数的域。)

I assumed I should write a nested for loop along the following: 我假设我应该沿着以下内容编写一个嵌套的for循环:

for (i in dt$color) 
  {(paste("fun_",i, sep = "")) = function(x)
    for (a in dt$a) 
      {a*x}
    }

However, I, a relative R newbie, can't quite get this for loop to work. 但是,我,一个相对较新的R新手,无法完全使此for循环正常工作。

I'd then like to plot each of these 10 equations on the same plot. 然后,我想将这10个方程式的每一个都绘制在同一图上。 I assume I should write another for loop here, something like: 我假设我应该在这里编写另一个for循环,例如:

plot(fun_red)
for (i in function_list) {
  plot(i, add=TRUE)}

Any help? 有什么帮助吗? Thanks! 谢谢!

Choose a sequence of x values, and iterate over them with sapply. 选择一个x值序列,然后用sapply遍历它们。 No need to call the plotting functions many times, just use matplot . 无需多次调用绘图函数,只需使用matplot

s <- seq(.2,5,by =.2)
matplot(s,t(sapply(s, function(x) dt$a*(x)^dt$b)),
        type = "l", lty = "solid", lwd = 2, col = dt$color, ylab = "y", xlab = "x")

在此处输入图片说明

Yes, use a for loop. 是的,使用for循环。 However, use curve for plotting functions. 但是,使用curve绘制函数。

plot.new()
plot.window(xlim = c(0, 5), ylim = c(0, 200))
for (i in seq_len(nrow(DF))) curve(DF$a[i] * (x ^ DF$b[i]), 
                                   add = TRUE, col = as.character(DF$color[i]),
                                   lwd = 2)
axis(1)  
axis(2)

结果图

The following does not use a for loop to create the functions but rather uses a function that returns a different function depending on the color given as argument. 以下内容不使用for循环来创建函数,而是使用根据参数给出的颜色返回不同函数的函数。 This has the advantage of not using assign and get . 这具有不使用assignget的优点。

fun_col <- function(col) {
  a <- dt$a[dt$color == col]
  b <- dt$b[dt$color == col]
  function(x) a*x^b
}

for (col in dt$color) {

  plot(fun_col(col), add = TRUE)

}

Alternatively, we can plot the functions with apply rather than the for loop. 另外,我们可以用apply而不是for循环来绘制函数。 First, let's read in data and the range of the values to plot. 首先,让我们读入数据和要绘制的值的范围。

dt <- read.table(text="color   a   b
red     3   1.3
blue    9   1.8
purple  13  1.2
green   4   1.1
orange  7   0.9
yellow  6   2.1
brown   7   1.8", header=T)

# vector for x values
x1 <- 0
x2 <- 1
n <- 100
x <- seq(x1, x2, by = ((x2-x1)/n))

Then, we plot an empty space into which the function curves will be plotted. 然后,我们绘制一个空白区域,在该空白区域中绘制函数曲线。 Note, that we calculate the maximum needed for the y axis in the max.y variable. 注意,我们在max.y变量中计算y轴所需的最大值。

max.y <- dt[which.max(rowSums(dt[,2:3])),2] * (x2 ^ dt[which.max(rowSums(dt[,2:3])),3])

plot(x1, type="n", xlim=c(x1,x2), ylim=c(x1, max.y), xlab="x", ylab="a*(x^b)")

And finally, we plot the lines according to the specifications in the data. 最后,我们根据数据中的规格绘制线。

apply(dt, 1, FUN=function(dt.row) 
    lines(x, as.numeric(dt.row[2]) * (x ^ as.numeric(dt.row[3])), col=dt.row[1]))

Benchmarking 标杆管理

As per Roland's and shayaa's comments, here is the performance comparison. 根据Roland和shayaa的评论,这是性能比较。 The whole answers from Roland and shayaa were fed into the respective functions, and everything from here starting from the x1 variable definition into the nya() function. Roland和shayaa的全部答案被馈送到各自的函数中,从这里开始,从x1变量定义到nya()函数的所有内容。

library(microbenchmark)
microbenchmark(roland(dt))
Unit: milliseconds
       expr      min      lq    mean   median       uq      max neval
 roland(dt) 18.09634 18.4124 19.2258 18.67313 19.17735 35.42943   100
microbenchmark(shayaa(dt=dt))
Unit: milliseconds
            expr      min       lq     mean   median       uq      max neval
 shayaa(dt = dt) 10.85788 11.04311 11.44358 11.22057 11.51216 18.19182   100
 microbenchmark(nya(dt=dt))
 Unit: milliseconds
          expr      min       lq     mean  median       uq      max neval
  nya(dt = dt) 18.26883 18.61892 19.02823 18.8229 19.18054 25.41353   100

I would conclude that in this case, performance is not a critical issue. 我可以得出结论,在这种情况下,性能不是关键问题。 The user might choose an approach based on personal preference and amend it with dynamic options for plot size (x1, x2, max.y). 用户可以根据个人喜好选择一种方法,并通过动态选项修改地块大小(x1,x2,最大y)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM