【问题标题】:R: Plotting Multiple Graphs using a "for loop"R:使用“for循环”绘制多个图
【发布时间】:2021-05-25 02:04:05
【问题描述】:

我正在使用 R 编程语言。

使用以下代码,我可以在同一页面上放置两个图:

#load library
library(dbscan)

#specify number of plots per page
par(mfrow = c(1,2))

#load libraries
library(dbscan)
library(dplyr)


#generate data
n <- 100
x <- cbind(
  x=runif(10, 0, 5) + rnorm(n, sd=0.4),
  y=runif(10, 0, 5) + rnorm(n, sd=0.4)
  )



### calculate LOF score
lof <- lof(x, k=3)

### distribution of outlier factors (first plot)
summary(lof)
hist(lof, breaks=10)

### point size is proportional to LOF (second plot)
plot(x, pch = ".", main = "LOF (k=3)")
points(x, cex = (lof-1)*3, pch = 1, col="red")

这会产生以下情节:

现在,我正在尝试在同一页面上制作多个图(例如 6 个图,2 对 3)。我尝试使用“for 循环”(对于 k = 3、4、5)来实现这一点:

par(mfrow = c(3,2))

vals <- 3:5
combine <- vector('list', length(vals))
count <- 0
for (i in vals) {
  

lof_i <- lof(x, k=i)

### distribution of outlier factors
summary(lof_i)
hist(lof_i, breaks=10)

### point size is proportional to LOF
plot(x, pch = ".", main = "LOF (k=i)")
points(x, cex = (lof_i-1)*3, pch = 1, col="red")
  }

但是,这似乎只是在同一页面上重复同一图表 6 次:

有人可以告诉我如何更正此代码吗?

是否也可以保存文件“lof_3、lof_4、lof_5”?似乎没有创建这些文件,只创建了“lof_i”:

> lof_3
Error: object 'lof_3' not found

> head(lof_i)
[1] 1.223307 1.033424 1.077149 1.011407 1.040634 1.431029

谢谢

【问题讨论】:

    标签: r for-loop plot histogram data-manipulation


    【解决方案1】:

    查看您的图,您似乎已经生成并绘制了不同的图,但要使标签正确,您需要将变量而不是固定字符传递给您的标题(例如,使用 paste 命令)。

    要从循环中获取计算值,您可以生成一个空列表并将循环中的结果分配给各个列表元素,或者使用 lapply 之类的东西,它会自动以列表形式返回结果。

    为了简化一些事情,您可以定义一个函数来绘制或返回计算值,例如像这样:

    library(dbscan)
    
    #generate data
    set.seed(123)
    n <- 100
    x <- cbind(
        x=runif(10, 0, 5) + rnorm(n, sd=0.4),
        y=runif(10, 0, 5) + rnorm(n, sd=0.4)
    )
    
    plotLOF <- function(i, plot=TRUE){
        lof <- lof(x, k=i)
        if (plot){
            hist(lof, breaks=10)
            plot(x, pch = ".", main = paste0("LOF (k=", i, ")"))
            points(x, cex = (lof-1)*3, pch = 1, col="red")
        } else return(lof)
    }
    
    par(mfrow = c(3,2))
    invisible(lapply(3:5, plotLOF))
    

    lapply(3:5, plotLOF, plot=FALSE)
    #> [[1]]
    #>   [1] 1.1419243 0.9551471 1.0777472 1.1224447 0.8799095 1.0377858 0.8416306
    #>   [8] 1.0487133 1.0250496 1.3183819 0.9896833 1.0353398 1.3088266 1.0123238
    #>  [15] 1.1233530 0.9685039 1.0589151 1.3147785 1.0488644 0.9212146 1.2568698
    #>  [22] 1.0086274 1.0454450 0.9661698 1.0644528 1.1107202 1.0942201 1.5147076
    #>  [29] 1.0321698 1.0553455 1.1149748 0.9341090 1.2352716 0.9478602 1.4096464
    #>  [36] 1.0519127 1.0507267 1.3199825 1.2525485 0.9361488 1.0958563 1.2131615
    #>  [43] 0.9943090 1.0123238 1.1060491 1.0377766 0.9803135 0.9627699 1.1165421
    #>  [50] 0.9796819 0.9946925 2.1576989 1.6015310 1.5670315 0.9343637 1.0033725
    #>  [57] 0.8769431 0.9783065 1.0800050 1.2768800 0.9735274 1.0377472 1.0743988
    #>  [64] 1.7583562 1.2662485 0.9685039 1.1662145 1.2491499 1.1131718 1.0085023
    #>  [71] 0.9636864 1.1538360 1.2126138 1.0609829 1.0679010 1.0490234 1.1403292
    #>  [78] 0.9638900 1.1863703 0.9651060 0.9503445 1.0098536 0.8440855 0.9052420
    #>  [85] 1.2662485 1.4447713 1.0845415 1.0661381 0.9282678 0.9380078 1.1414628
    #>  [92] 1.0407138 1.0942201 1.0589805 1.0370938 1.0147094 1.1067291 0.8834466
    #>  [99] 1.7027132 1.1766560
    #> 
    #> [[2]]
    #>   [1] 1.1667311 1.0409009 1.0920953 1.0068953 0.9894195 1.1332413 0.9764505
    #>   [8] 1.0228796 1.0446905 1.0893386 1.1211637 1.1029415 1.3453498 0.9712910
    #>  [15] 1.1635936 1.0265746 0.9480282 1.2144437 1.0570346 0.9314618 1.3345561
    #>  [22] 0.9816097 0.9929112 1.0322014 1.2739621 1.2947553 1.0202948 1.6153264
    #>  [29] 1.0790922 0.9987830 1.0378609 0.9622779 1.2974938 0.9129639 1.2601398
    #>  [36] 1.0265746 1.0241622 1.2420568 1.2204376 0.9297345 1.1148404 1.2546361
    #>  [43] 1.0059582 0.9819820 1.0342491 0.9452673 1.0369500 0.9791091 1.2000825
    #>  [50] 0.9878844 1.0205586 2.0057587 1.2757014 1.5347815 0.9622614 1.0692613
    #>  [57] 1.0026404 0.9408510 1.0280687 1.3534531 0.9669894 0.9300601 0.9929112
    #>  [64] 1.7567871 1.3861828 1.0265746 1.1120151 1.3542396 1.1562077 0.9842179
    #>  [71] 1.0301098 1.2326327 1.1866352 1.0403814 1.0577086 0.8745912 1.0017905
    #>  [78] 0.9904356 1.0602487 0.9501681 1.0176457 1.0405430 0.9718224 1.0046821
    #>  [85] 1.1909982 1.6151918 0.9640852 1.0141963 1.0270237 0.9867738 1.1474414
    #>  [92] 1.1293307 1.0323945 1.0859417 0.9622614 1.0290635 1.0186381 0.9225209
    #>  [99] 1.6456612 1.1366753
    #> 
    #> [[3]]
    #>   [1] 1.1299335 1.0122028 1.2077092 0.9485150 1.0115694 1.1190314 0.9989174
    #>   [8] 1.0145663 1.0357546 0.9783702 1.1050504 1.0661798 1.3571416 1.0024603
    #>  [15] 1.1484745 1.0162149 0.9601474 1.1310442 1.0957731 1.0065501 1.2687934
    #>  [22] 0.9297323 0.9725355 0.9876444 1.2314822 1.2209304 0.9906446 1.4249452
    #>  [29] 1.2156607 0.9959685 1.0304305 0.9976110 1.1711354 1.0048161 0.9813000
    #>  [36] 1.0128909 0.9730295 1.1741982 1.3317209 0.9708714 1.0994309 1.1900047
    #>  [43] 0.9960765 0.9659553 0.9744357 0.9556112 1.0508484 0.9669406 1.3919743
    #>  [50] 0.9467537 1.0596883 1.7396644 1.1323109 1.6516971 0.9922995 1.0223594
    #>  [57] 0.9917594 0.9542419 1.0672565 1.2274498 1.0589385 0.9649404 0.9953886
    #>  [64] 1.7666795 1.3111620 0.9860706 1.0576620 1.2547512 1.0038281 0.9825967
    #>  [71] 1.0104708 1.1739417 1.1884817 1.0199412 0.9956941 0.9720389 0.9601474
    #>  [78] 0.9898781 1.1025485 0.9797453 1.0086780 1.0556471 1.0150204 1.0339022
    #>  [85] 1.1174116 1.5252177 0.9721734 0.9486663 1.0161640 0.9903872 1.2339874
    #>  [92] 1.0753099 0.9819882 1.0439012 1.0016272 1.0122706 1.0536213 0.9948601
    #>  [99] 1.4693656 1.0274264
    

    reprex package (v1.0.0) 于 2021 年 2 月 22 日创建

    【讨论】:

    • 感谢您的帮助!你能解释一下你的逻辑吗?为什么定义一个新函数(plotLOF)比使用“for循环”更好?
    • 如果你有时间,你能不能在这里看看这个问题:stackoverflow.com/questions/66322659/…谢谢你的帮助!
    • for 循环本身并不比在函数上执行 lapply 更好/更差——在某些情况下,您可能会从并行化中受益,例如只需将lapply 替换为parallel::mclapply)。通常,在重复某些操作并稍作修改时,函数会很方便,您也可以在循环中使用这样的函数(这里:for (i in 3:5) plotLOF(i))。你甚至可以向量化一个函数(这里:plotLOF &lt;- Vectorize(plotLOF),然后运行plotLOF(3:5))。此外,lapply 生成一个列表输出,而在循环中您需要显式填充或附加一个列表。
    【解决方案2】:
    for i in vector
        eval(parse(text = sprintf("plot(df$%s)",i)))
    

    这是非常强大的代码行...可以非常方便地绘制带有循环的图形。

    【讨论】:

    • 感谢您的回复!你能用这段代码写出完整的答案吗?谢谢!
    猜你喜欢
    • 2022-01-05
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2020-09-06
    相关资源
    最近更新 更多