我在这里添加我的练习代码以供参考。说明如下。
aes_()
在运行上述代码时,它将仅打印library(shiny)
library(ggplot2)
ui <- (fluidPage(
titlePanel("Pig Breeds"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "x",
label = "Pig Breeds:",
choices = c("total_pigs", "female_breeding_herd",
"in_pig_sows", "in_pig_gifts", "other_sows",
"maiden_gilts", "boars_for_service", "other_pigs"),
selected = "total_pigs"),
selectInput(inputId = "y",
label = "Year by year change:",
choices = c(2016, 2017, 2018, "year_on_year_change"),
selected = 2016),
actionButton(inputId = "update", label = "update")
),
mainPanel = (
plotOutput(outputId = "scatterplot")
)
)
)
)
server <- (function(input, output) {
output$scatterplot <- renderPlot({
ggplot(data=(read.csv("eu_pigs.csv")),
aes(x = output$x, y = output$y) +
geom_point())
observeEvent(input$update, {print(as.numeric(input$update))})
}
)
}
)
shinyApp(ui, server)
一次。这是用于此宏中的 (defmacro block [ctx & expr]
(println expr)
`(let [~@(mapcat (fn [[k v]] [k `~v]) ctx)] ~@expr))
(defmacro uia [metadata ctx arity & expr]
`(block ~metadata
(fn ~arity (prn "got" ~arity ~'mt))
)
)
(def auto1 (uia {mt "dt"}
[{ et "wa" s "a1"}
{et "wa" s "a2"}
{et "um" s "a3"}] [et1 id cid]
(block {} (prn "auto1"))
))
(let [myarr ["x" 11 22]] (apply auto1 myarr))
。
现在,我想打印它,具体取决于在"got" ["x" 11 22] "dt"
内部传递给函数arity
的元素数量。
例如:
从ctx
,我将3个必选参数传递给uia
:
元数据:auto1
ctx :uia
种族:{mt "dt"}
现在[{ et1 "wa" s "a1"} {et1 "wa" s "a2"} {et1 "um" s "a3"}]
是一个带有3个映射的向量。我想在[et id cid]
内部调用匿名函数3次。这样它将立即打印;
ctx
uia
"got" "x" 11 22 wa a1 "dt" --> on first call
因此根据代码的相应输出语句将为;
"got" "x" 11 22 wa a2 "dt" --> on second call
请给我建议一种可以实现它的方法。
注意:
"got" "x" 11 22 um a3 "dt" --> on third call
内部完成。如果需要一些与此有关的额外信息,请告诉我。
答案 0 :(得分:1)
您通过调用uia
返回的最终函数在任何地方都不包括上下文映射:
>>> (macroexpand-1
'(uia {mt "dt"}
[{ et "wa" s "a1"}
{et "wa" s "a2"}
{et "um" s "a3"}]
[et1 id cid]
(block {} (prn "auto1"))))
(user/block
{mt "dt"}
(clojure.core/fn [et1 id cid]
(clojure.core/prn "got" [et1 id cid] mt)))
>>> (macroexpand-1
'(user/block
{mt "dt"}
(clojure.core/fn [et1 id cid]
(clojure.core/prn "got" [et1 id cid] mt))))
(clojure.core/let [mt "dt"]
(clojure.core/fn [et1 id cid] (
clojure.core/prn "got" [et1 id cid] mt)))
结果是使用您指定的ariety的函数,并且将封闭的自由变量mt
绑定到“ dt”-找不到上下文映射。
我怀疑您对block
的定义不是您想要的,或者至少签名是错误的。
(defmacro block [ctx & expr]
`(let [~@(mapcat (fn [[k v]] [k v]) ctx)] ~@expr))
您传递给块的实际参数是元数据映射,而不是上下文映射。如果有意,我将更改签名以反映在签名和正文中将ctx
替换为mt
。
关于为什么它只打印3次,请看上面的最后扩展应该清楚-返回的闭包接受3个参数,然后将它们与metdata一起打印在向量中(由闭合符号{{1引用}}从外部mt
。
let
有了此更改,现在当您调用(defmacro uia [metadata ctx arity & expr]
`(block ~metadata
(fn ~arity
(dotimes [n# ~(count ctx)]
(prn "got" ~arity ~'mt)))))
时,以下打印内容:
uia
这是朝着正确方向迈出的一步,但您的问题表明您还希望将地图内的值以及封闭的元数据和3个函数参数一起打印出来。要基于上下文映射中的项目进行打印,需要进行两项更改:
首先,上下文映射键需要用引号符号"got" ["x" 11 22] "dt"
"got" ["x" 11 22] "dt"
"got" ["x" 11 22] "dt"
而不是'et
或关键字。这是因为返回的映射试图在运行时评估未绑定的未引用符号键(假设您没有绑定它们的某些全局上下文(未提供)。
第二,您需要遍历返回函数内的每个映射,并提取相关值。除了将映射键从符号更改为关键字之外,唯一的其他更改是根据请求对et
进行更改,对我而言,无论如何都将更改保留在其中最容易。
uia