Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
Radiant
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wuzekai
Radiant
Commits
f261dcec
Commit
f261dcec
authored
Dec 03, 2025
by
wuzekai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
更新了大模型调用方式
parent
b3e914bc
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1028 additions
and
37 deletions
+1028
-37
NAMESPACE
radiant.quickgen/NAMESPACE
+10
-5
quickgen_chart.R
radiant.quickgen/R/quickgen_chart.R
+95
-0
quickgen_metrics.R
radiant.quickgen/R/quickgen_metrics.R
+96
-0
help.R
radiant.quickgen/inst/app/help.R
+2
-1
init.R
radiant.quickgen/inst/app/init.R
+5
-2
quickgen_basic_ui.R
radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R
+1
-1
quickgen_chart_ui.R
radiant.quickgen/inst/app/tools/analysis/quickgen_chart_ui.R
+302
-0
quickgen_chat_ui.R
radiant.quickgen/inst/app/tools/analysis/quickgen_chat_ui.R
+1
-1
quickgen_metrics_ui.R
...nt.quickgen/inst/app/tools/analysis/quickgen_metrics_ui.R
+419
-0
quickgen_ai.md
radiant.quickgen/inst/app/tools/help/quickgen_ai.md
+0
-27
quickgen_chart.md
radiant.quickgen/inst/app/tools/help/quickgen_chart.md
+52
-0
quickgen_chat.md
radiant.quickgen/inst/app/tools/help/quickgen_chat.md
+44
-0
quickgen_metrics.md
radiant.quickgen/inst/app/tools/help/quickgen_metrics.md
+1
-0
No files found.
radiant.quickgen/NAMESPACE
View file @
f261dcec
...
@@ -3,11 +3,12 @@
...
@@ -3,11 +3,12 @@
S3method(dtab,explore)
S3method(dtab,explore)
S3method(store,explore)
S3method(store,explore)
S3method(summary,explore)
S3method(summary,explore)
export(ai_generate)
export(build_chart_prompt)
export(ai_get_data_call)
export(build_metrics_prompt)
export(ai_run_code)
export(chart_completion)
export(build_r_prompt)
export(chart_generate)
export(chat_completion)
export(chart_get_data_call)
export(chart_run_code)
export(cv)
export(cv)
export(does_vary)
export(does_vary)
export(empty_level)
export(empty_level)
...
@@ -16,6 +17,10 @@ export(flip)
...
@@ -16,6 +17,10 @@ export(flip)
export(ln)
export(ln)
export(me)
export(me)
export(meprop)
export(meprop)
export(metrics_completion)
export(metrics_generate)
export(metrics_get_data_call)
export(metrics_run_code)
export(modal)
export(modal)
export(n_missing)
export(n_missing)
export(n_obs)
export(n_obs)
...
...
radiant.quickgen/R/quickgen_
ai
.R
→
radiant.quickgen/R/quickgen_
chart
.R
View file @
f261dcec
# === 配置 ===
# === 配置 ===
MODELSCOPE_OPENAI_URL
<-
"https://api-inference.modelscope.cn/v1"
OLLAMA_URL
<-
"http://180.169.131.147:8139/api/generate"
MODELSCOPE_API_KEY
<-
Sys.getenv
(
"MODELSCOPE_API_KEY"
,
"ms-5b9f3668-ea8e-4a2c-8cd3-a1a9ba04810b"
)
MODEL_ID
<-
"qwen3-coder:30b"
MODEL_ID
<-
"deepseek-ai/DeepSeek-V3.1"
# === 单次对话 ===
# === 单次对话 ===
#' @export
#' @export
chat_completion
<-
function
(
user_prompt
,
chart_completion
<-
function
(
user_prompt
)
{
max_tokens
=
1500
,
temperature
=
0.3
)
{
req
<-
httr2
::
request
(
paste0
(
MODELSCOPE_OPENAI_URL
,
"/chat/completions"
))
%>%
httr2
::
req_headers
(
"Authorization"
=
paste
(
"Bearer"
,
MODELSCOPE_API_KEY
),
"Content-Type"
=
"application/json"
)
%>%
httr2
::
req_body_json
(
list
(
model
=
MODEL_ID
,
messages
=
list
(
list
(
role
=
"user"
,
content
=
user_prompt
)),
temperature
=
temperature
,
max_tokens
=
max_tokens
,
stream
=
FALSE
))
resp
<-
httr2
::
req_perform
(
req
)
Sys.unsetenv
(
"http_proxy"
)
body
<-
httr2
::
resp_body_json
(
resp
)
Sys.unsetenv
(
"https_proxy"
)
if
(
is.null
(
body
$
choices
[[
1
]]
$
message
$
content
))
# 构建请求体
stop
(
"ModelScope API 返回空内容:"
,
body
)
req_body
<-
list
(
model
=
MODEL_ID
,
prompt
=
user_prompt
,
stream
=
FALSE
)
# 使用 curl 包发送请求
h
<-
curl
::
new_handle
()
curl
::
handle_setheaders
(
h
,
"Content-Type"
=
"application/json"
)
curl
::
handle_setopt
(
h
,
postfields
=
jsonlite
::
toJSON
(
req_body
,
auto_unbox
=
TRUE
))
curl
::
handle_setopt
(
h
,
timeout
=
60
)
con
<-
curl
::
curl
(
OLLAMA_URL
,
handle
=
h
)
result
<-
readLines
(
con
,
warn
=
FALSE
)
close
(
con
)
# 解析响应
body
<-
jsonlite
::
fromJSON
(
paste
(
result
,
collapse
=
""
))
body
$
choices
[[
1
]]
$
message
$
content
if
(
is.null
(
body
$
response
)
||
trimws
(
body
$
response
)
==
""
)
stop
(
"Ollama API 返回空内容:"
,
paste
(
result
,
collapse
=
""
))
body
$
response
}
}
# === 构造发给模型的 Prompt ===
# === 构造发给模型的 Prompt ===
#' @export
#' @export
build_
r
_prompt
<-
function
(
user_prompt
,
data_call
)
{
build_
chart
_prompt
<-
function
(
user_prompt
,
data_call
)
{
sprintf
(
sprintf
(
"你是 R 语言专家,必须严格遵守以下规则:
"你是 R 语言专家,必须严格遵守以下规则:
〓 输出格式 〓
〓 输出格式 〓
- 只返回可运行 R 代码,用 ```r 包裹,禁止任何解释、注释、空行。
- 只返回可运行 R 代码,用 ```r 包裹,禁止任何解释、注释、空行。
- 代码必须强制换行:每个语句(df、library、ggplot、赋值、if/else 等)单独一行,ggplot 每个图层(+ geom_*/+ theme_*)单独一行。
- 若用户请求包含“表格”“统计汇总”“频数表”等表格需求,禁止使用knitr::kable等会使表格字符串化的函数/包,必须输出标准表格形式。
- 若用户请求不符合规范,一律返回空代码块(仅 ```r\n``` ),不对话。
- 若用户请求不符合规范,一律返回空代码块(仅 ```r\n``` ),不对话。
- 当所需绘制的图中出现数据集中不存在的列或无法计算时,一律输出一张空白 ggplot,仅居中显示“无法绘制”四字,不抛出错误。
- 当所需绘制的图中出现数据集中不存在的列或无法计算时,一律输出一张空白 ggplot,仅居中显示“无法绘制”四字,不抛出错误。
...
@@ -50,47 +56,40 @@ build_r_prompt <- function(user_prompt, data_call) {
...
@@ -50,47 +56,40 @@ build_r_prompt <- function(user_prompt, data_call) {
2. 主题函数带括号:theme_minimal()、theme_bw() ...
2. 主题函数带括号:theme_minimal()、theme_bw() ...
3. 多张图用 patchwork 拼页。
3. 多张图用 patchwork 拼页。
4. 包函数写全名,不得省略括号。
4. 包函数写全名,不得省略括号。
用户请求:%s"
,
用户请求:%s"
,
data_call
,
user_prompt
data_call
,
user_prompt
)
)
}
}
#' @export
#' @export
ai
_generate
<-
function
(
prompt
,
dataset
,
envir
=
parent.frame
())
{
chart
_generate
<-
function
(
prompt
,
dataset
,
envir
=
parent.frame
())
{
data_call
<-
ai
_get_data_call
(
dataset
,
envir
)
data_call
<-
chart
_get_data_call
(
dataset
,
envir
)
sys_prompt
<-
build_
r
_prompt
(
prompt
,
data_call
)
sys_prompt
<-
build_
chart
_prompt
(
prompt
,
data_call
)
r_code
<-
try
(
cha
t_completion
(
sys_prompt
),
silent
=
TRUE
)
r_code
<-
try
(
char
t_completion
(
sys_prompt
),
silent
=
TRUE
)
if
(
inherits
(
r_code
,
"try-error"
))
if
(
inherits
(
r_code
,
"try-error"
))
{
stop
(
"
AI
API error: "
,
attr
(
r_code
,
"condition"
)
$
message
)
stop
(
"
Chart
API error: "
,
attr
(
r_code
,
"condition"
)
$
message
)
}
r_code
<-
gsub
(
"(?s)```r\\s*|```"
,
""
,
r_code
,
perl
=
TRUE
)
r_code
<-
gsub
(
"(?s)```r\\s*|```"
,
""
,
r_code
,
perl
=
TRUE
)
r_code
<-
trimws
(
r_code
)
r_code
<-
trimws
(
r_code
)
if
(
r_code
==
""
)
{
if
(
r_code
==
""
)
{
return
(
list
(
r_code
=
""
,
return
(
list
(
r_code
=
""
,
type
=
"empty"
,
auto_run
=
FALSE
))
type
=
"empty"
,
auto_run
=
FALSE
))
}
}
r_code
<-
gsub
(
"(?s)df\\s*<-\\s*(eval\\(quote\\(get_data\\(|get_data\\()[^;\\n]+;"
,
""
,
r_code
,
perl
=
TRUE
)
r_code
<-
gsub
(
"(theme_minimal|theme_bw|theme_classic|theme_gray|theme_void|theme_dark)\\b(?!\\s*\\()"
,
r_code
<-
trimws
(
r_code
)
"\\1()"
,
r_code
,
perl
=
TRUE
)
r_code
<-
gsub
(
"(theme_minimal|theme_bw|theme_classic|theme_gray|theme_void|theme_dark)\\b(?!\\s*\\()"
,
"\\1()"
,
r_code
,
perl
=
TRUE
)
r_code
<-
paste0
(
data_call
,
"\n"
,
r_code
)
has_gg
<-
grepl
(
"ggplot\\(|geom_"
,
r_code
)
has_gg
<-
grepl
(
"ggplot\\(|geom_"
,
r_code
)
has_tbl
<-
grepl
(
"data\\.frame\\(|tibble\\(|tbl_summary|tableOne|CreateTableOne"
,
r_code
)
has_tbl
<-
grepl
(
"data\\.frame\\(|tibble\\(|tbl_summary|tableOne|CreateTableOne"
,
r_code
)
type
<-
if
(
has_gg
)
"plot"
else
if
(
has_tbl
)
"table"
else
"text"
type
<-
if
(
has_gg
)
"plot"
else
if
(
has_tbl
)
"table"
else
"text"
list
(
r_code
=
r_code
,
type
=
type
,
auto_run
=
TRUE
)
list
(
r_code
=
r_code
,
type
=
type
,
auto_run
=
TRUE
)
}
}
#' @export
#' @export
ai
_get_data_call
<-
function
(
dataset
,
envir
)
{
chart
_get_data_call
<-
function
(
dataset
,
envir
)
{
df_name
<-
if
(
is_string
(
dataset
))
dataset
else
deparse1
(
substitute
(
dataset
))
df_name
<-
if
(
is_string
(
dataset
))
dataset
else
deparse1
(
substitute
(
dataset
))
paste0
(
"df <- eval(quote(get_data(\""
,
df_name
,
"\", envir = "
,
paste0
(
"df <- eval(quote(get_data(\""
,
df_name
,
"\", envir = "
,
deparse1
(
substitute
(
envir
)),
")), envir = parent.frame())"
)
deparse1
(
substitute
(
envir
)),
")), envir = parent.frame())"
)
}
}
#' @export
#' @export
ai
_run_code
<-
function
(
r_code
,
envir
=
parent.frame
())
{
chart
_run_code
<-
function
(
r_code
,
envir
=
parent.frame
())
{
eval
(
parse
(
text
=
r_code
),
envir
=
envir
)
eval
(
parse
(
text
=
r_code
),
envir
=
envir
)
}
}
\ No newline at end of file
radiant.quickgen/R/quickgen_metrics.R
0 → 100644
View file @
f261dcec
# === 配置 ===
OLLAMA_URL
<-
"http://172.29.2.110:8139/api/generate"
MODEL_ID
<-
"qwen3-coder:30b"
# === 单次对话 ===
#' @export
metrics_completion
<-
function
(
user_prompt
)
{
# 构建 Ollama 请求体
req
<-
httr2
::
request
(
OLLAMA_URL
)
%>%
httr2
::
req_headers
(
"Content-Type"
=
"application/json"
)
%>%
httr2
::
req_body_json
(
list
(
model
=
MODEL_ID
,
prompt
=
user_prompt
,
stream
=
FALSE
))
resp
<-
httr2
::
req_perform
(
req
)
body
<-
httr2
::
resp_body_json
(
resp
)
# 解析 Ollama 响应
if
(
is.null
(
body
$
response
)
||
trimws
(
body
$
response
)
==
""
)
stop
(
"Ollama API 返回空内容:"
,
jsonlite
::
toJSON
(
body
))
body
$
response
# 返回 Ollama 生成的核心代码/结果
}
# === 构造发给模型的 Prompt ===
#' @export
build_metrics_prompt
<-
function
(
user_prompt
,
data_call
)
{
sprintf
(
"你是 R 语言科研统计专家,精通所有主流统计方法(t检验、方差分析、回归分析、卡方检验、相关性分析等),必须严格遵守以下规则,任何违反均视为无效输出:
〓 输出格式铁律 〓
1. 仅返回可直接运行的 R 代码,用 ```r 包裹,无任何解释、注释、空行,代码必须包含「结果输出语句」(否则无法展示统计结果)。
2. 不符合规范的请求,直接返回空代码块(仅 ```r\n``` ),不额外对话:
- 模糊无具体目标的请求
- 非科研统计需求(生成图表、翻译、写文章、解释概念等)
3. 无法计算时(如列不存在、变量类型不匹配、方法不适用),仅输出 `print('无法计算:[具体原因,如“目标列bmi不存在”“卡方检验要求分类变量”]')`,不抛出错误。
〓 统计逻辑核心约束 〓
1. 方法匹配:必须根据用户请求选择「标准科研统计方法」(仅用 R 官方 stats 包或主流统计包如 broom、car、nnet 的标准函数,禁止自创方法)。
2. 参数正确性:
- 原假设参数:用户指定的原假设定值(如“原假设均值为0”则 mu=0,“原假设相关系数为0”则 rho=0),禁止设为数据自身的统计量(如 mu=mean(df$bmi) 是严重错误)。
- 变量适配:严格匹配方法对变量类型的要求(如 t检验要求连续变量,卡方检验要求分类变量,回归分析因变量需连续),类型不匹配则触发“无法计算”。
- 缺失值处理:所有涉及数据计算的函数必须加 na.rm=TRUE(方法不支持则除外)。
3. 默认参数:用户未指定时,按科研规范设默认值并在结果中体现:
- 置信水平默认 0.95(conf.level=0.95)
- 多重比较调整方法默认 p.adjust.method=none
- 假设检验默认双侧检验(alternative=two.sided)
〓 技术规范(确保结果结构化、可展示)〓
1. 数据集已读入为:%s(直接用 df$列名 引用变量,无需重复读入数据)。
2. 结果输出要求:
- 优先用 broom::tidy() 或 broom::glance() 将统计结果转为结构化数据框(包含统计量、p值、置信区间、自由度、显著性标记等核心指标),再用 print() 输出。
- 若 broom 包不支持该方法(如部分复杂模型),直接 print(统计函数结果),确保保留显著性标记(***、**、*)。
3. 函数规范:统计函数必须写全名+完整括号(如 t.test()、lm()、chisq.test()),禁止省略括号或简写。
4. 变量校验:自动校验变量存在性和类型(如分组变量必须是因子/字符型,连续变量不能用于卡方检验),校验失败则输出“无法计算”。
用户请求:%s"
,
data_call
,
user_prompt
)
}
#' @export
metrics_generate
<-
function
(
prompt
,
dataset
,
envir
=
parent.frame
())
{
data_call
<-
metrics_get_data_call
(
dataset
,
envir
)
sys_prompt
<-
build_metrics_prompt
(
prompt
,
data_call
)
r_code
<-
try
(
metrics_completion
(
sys_prompt
),
silent
=
TRUE
)
if
(
inherits
(
r_code
,
"try-error"
))
stop
(
"Metrics API error: "
,
attr
(
r_code
,
"condition"
)
$
message
)
r_code
<-
gsub
(
"(?s)```r\\s*|```"
,
""
,
r_code
,
perl
=
TRUE
)
r_code
<-
trimws
(
r_code
)
if
(
r_code
==
""
)
{
return
(
list
(
r_code
=
""
,
type
=
"empty"
,
auto_run
=
FALSE
))
}
r_code
<-
paste0
(
data_call
,
"\n"
,
r_code
)
has_gg
<-
grepl
(
"ggplot\\(|geom_"
,
r_code
)
has_tbl
<-
grepl
(
"data\\.frame\\(|tibble\\(|tbl_summary|tableOne|CreateTableOne|t.test|lm|cor.test|anova"
,
r_code
)
type
<-
if
(
has_gg
)
"plot"
else
if
(
has_tbl
)
"table"
else
"text"
list
(
r_code
=
r_code
,
type
=
type
,
auto_run
=
TRUE
)
}
#' @export
metrics_get_data_call
<-
function
(
dataset
,
envir
)
{
df_name
<-
if
(
is_string
(
dataset
))
dataset
else
deparse1
(
substitute
(
dataset
))
paste0
(
"df <- eval(quote(get_data(\""
,
df_name
,
"\", envir = "
,
deparse1
(
substitute
(
envir
)),
")), envir = parent.frame())"
)
}
#' @export
metrics_run_code
<-
function
(
r_code
,
envir
=
parent.frame
())
{
eval
(
parse
(
text
=
r_code
),
envir
=
envir
)
}
radiant.quickgen/inst/app/help.R
View file @
f261dcec
help_quickgen
<-
c
(
help_quickgen
<-
c
(
"一键生成描述性统计"
=
"quickgen_basic.md"
,
"一键生成描述性统计"
=
"quickgen_basic.md"
,
"大模型对话引导助手"
=
"quickgen_chat.md"
,
"大模型对话引导助手"
=
"quickgen_chat.md"
,
"大模型生成描述性统计"
=
"quickgen_ai.md"
"大模型生成描述性统计(图表)"
=
"quickgen_chart.md"
,
"大模型生成描述性统计(指标)"
=
"quickgen_metrics.md"
)
)
output
$
help_quickgen
<-
reactive
(
append_help
(
"help_quickgen"
,
file.path
(
getOption
(
"radiant.path.quickgen"
),
"app/tools/help"
),
Rmd
=
TRUE
))
output
$
help_quickgen
<-
reactive
(
append_help
(
"help_quickgen"
,
file.path
(
getOption
(
"radiant.path.quickgen"
),
"app/tools/help"
),
Rmd
=
TRUE
))
...
...
radiant.quickgen/inst/app/init.R
View file @
f261dcec
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
r_url_list
<-
getOption
(
"radiant.url.list"
)
r_url_list
<-
getOption
(
"radiant.url.list"
)
r_url_list
[[
"Generate descriptive statistics with one click"
]]
<-
"quickgen/basic/"
r_url_list
[[
"Generate descriptive statistics with one click"
]]
<-
"quickgen/basic/"
r_url_list
[[
"AI chat guidance"
]]
<-
"quickgen/chat/"
r_url_list
[[
"AI chat guidance"
]]
<-
"quickgen/chat/"
r_url_list
[[
"
LLM generates descriptive statistics"
]]
<-
"quickgen/ai/
"
r_url_list
[[
"
AI generates descriptive statistics(chart)"
]]
<-
"quickgen/chart
"
options
(
radiant.url.list
=
r_url_list
)
options
(
radiant.url.list
=
r_url_list
)
rm
(
r_url_list
)
rm
(
r_url_list
)
...
@@ -15,9 +15,12 @@ options(
...
@@ -15,9 +15,12 @@ options(
tags
$
head
(
tags
$
head
(
tags
$
script
(
src
=
"www_quickgen/js/run_return.js"
)
tags
$
script
(
src
=
"www_quickgen/js/run_return.js"
)
),
),
"----"
,
i
18
n
$
t
(
"Quick Statistics"
),
tabPanel
(
i
18
n
$
t
(
"Generate descriptive statistics with one click"
),
uiOutput
(
"quickgen_basic"
)),
tabPanel
(
i
18
n
$
t
(
"Generate descriptive statistics with one click"
),
uiOutput
(
"quickgen_basic"
)),
"----"
,
i
18
n
$
t
(
"AI assistance"
),
tabPanel
(
i
18
n
$
t
(
"AI chat guidance"
),
uiOutput
(
"quickgen_chat"
)),
tabPanel
(
i
18
n
$
t
(
"AI chat guidance"
),
uiOutput
(
"quickgen_chat"
)),
tabPanel
(
i
18
n
$
t
(
"AI generates descriptive statistics"
),
uiOutput
(
"quickgen_ai"
))
tabPanel
(
i
18
n
$
t
(
"AI generates descriptive statistics(chart)"
),
uiOutput
(
"quickgen_chart"
)),
tabPanel
(
i
18
n
$
t
(
"AI generates descriptive statistics(metrics)"
),
uiOutput
(
"quickgen_metrics"
)),
)
)
)
)
)
)
\ No newline at end of file
radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R
View file @
f261dcec
...
@@ -1145,7 +1145,7 @@ observeEvent(input$qgb_invert_selection, {
...
@@ -1145,7 +1145,7 @@ observeEvent(input$qgb_invert_selection, {
output
$
quickgen_basic
<-
renderUI
({
output
$
quickgen_basic
<-
renderUI
({
stat_tab_panel
(
stat_tab_panel
(
menu
=
i
18
n
$
t
(
"Oneclick generation >
Generate descriptive s
tatistics"
),
menu
=
i
18
n
$
t
(
"Oneclick generation >
Quick S
tatistics"
),
tool
=
i
18
n
$
t
(
"Generate descriptive statistics with one click"
),
tool
=
i
18
n
$
t
(
"Generate descriptive statistics with one click"
),
tool_ui
=
"ui_quickgen_basic"
,
tool_ui
=
"ui_quickgen_basic"
,
output_panels
=
tagList
(
output_panels
=
tagList
(
...
...
radiant.quickgen/inst/app/tools/analysis/quickgen_
ai
_ui.R
→
radiant.quickgen/inst/app/tools/analysis/quickgen_
chart
_ui.R
View file @
f261dcec
# quickgen_
ai
_ui.R
# quickgen_
chart
_ui.R
library
(
shinyjs
)
library
(
shinyjs
)
library
(
shinyAce
)
library
(
shinyAce
)
## ==================== 右下角浮框 ====================
## ==================== 右下角浮框 ====================
ui_
ai
_progress
<-
tags
$
div
(
ui_
chart
_progress
<-
tags
$
div
(
id
=
"
ai
_progress_box"
,
id
=
"
chart
_progress_box"
,
style
=
"display:none;
style
=
"display:none;
position:fixed;
position:fixed;
bottom:15px; right:15px;
bottom:15px; right:15px;
...
@@ -12,15 +12,15 @@ ui_ai_progress <- tags$div(
...
@@ -12,15 +12,15 @@ ui_ai_progress <- tags$div(
background:#f5f5f5; color:#333;
background:#f5f5f5; color:#333;
border:1px solid #337ab7; border-radius:4px;
border:1px solid #337ab7; border-radius:4px;
padding:10px 15px; box-shadow:0 2px 8px rgba(0,0,0,.25);"
,
padding:10px 15px; box-shadow:0 2px 8px rgba(0,0,0,.25);"
,
tags
$
strong
(
i
18
n
$
t
(
"AI
runn
ing..."
)),
tags
$
strong
(
i
18
n
$
t
(
"AI
generat
ing..."
)),
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
style
=
"width:100%"
))
style
=
"width:100%"
))
)
)
## ======== 警告弹窗========
## ======== 警告弹窗========
ui_
ai
_warn
<-
tags
$
div
(
ui_
chart
_warn
<-
tags
$
div
(
id
=
"
ai
_warn_box"
,
id
=
"
chart
_warn_box"
,
style
=
"display:none;
style
=
"display:none;
position:fixed;
position:fixed;
bottom:15px; right:15px;
bottom:15px; right:15px;
...
@@ -32,203 +32,199 @@ ui_ai_warn <- tags$div(
...
@@ -32,203 +32,199 @@ ui_ai_warn <- tags$div(
)
)
## ==================== 统一入口 ====================
## ==================== 统一入口 ====================
output
$
quickgen_
ai
<-
renderUI
({
output
$
quickgen_
chart
<-
renderUI
({
stat_tab_panel
(
stat_tab_panel
(
menu
=
i
18
n
$
t
(
"Oneclick generation > AI
generates descriptive statistics
"
),
menu
=
i
18
n
$
t
(
"Oneclick generation > AI
assistance
"
),
tool
=
i
18
n
$
t
(
"AI generates descriptive statistics"
),
tool
=
i
18
n
$
t
(
"AI generates descriptive statistics
(chart)
"
),
tool_ui
=
"
ai
_main_ui"
,
tool_ui
=
"
chart
_main_ui"
,
output_panels
=
tabPanel
(
output_panels
=
tabPanel
(
title
=
i
18
n
$
t
(
"
AI a
ssistant"
),
title
=
i
18
n
$
t
(
"
Chart A
ssistant"
),
value
=
"
ai
_panel"
,
value
=
"
chart
_panel"
,
uiOutput
(
"
ai
_result_area"
)
uiOutput
(
"
chart
_result_area"
)
)
)
)
)
})
})
## ==================== 右侧
AI
面板 ====================
## ==================== 右侧
Chart
面板 ====================
output
$
ai
_main_ui
<-
renderUI
({
output
$
chart
_main_ui
<-
renderUI
({
tagList
(
tagList
(
useShinyjs
(),
useShinyjs
(),
ui_
ai
_progress
,
ui_
chart
_progress
,
ui_
ai
_warn
,
ui_
chart
_warn
,
wellPanel
(
wellPanel
(
i
18
n
$
t
(
"Describe your analysis request"
),
i
18
n
$
t
(
"Describe your analysis request"
),
returnTextAreaInput
(
"
ai
_prompt"
,
returnTextAreaInput
(
"
chart
_prompt"
,
label
=
NULL
,
label
=
NULL
,
placeholder
=
i
18
n
$
t
(
"e. g. Please help me
draw a scatter plot of diamonds prices and carats
"
),
placeholder
=
i
18
n
$
t
(
"e. g. Please help me
generate a cross frequency histogram of sex and smoker
"
),
rows
=
4
,
rows
=
4
,
value
=
state_init
(
"
ai
_prompt"
,
""
)),
value
=
state_init
(
"
chart
_prompt"
,
""
)),
fluidRow
(
fluidRow
(
column
(
6
,
uiOutput
(
"ui_
ai
_submit"
)),
column
(
6
,
uiOutput
(
"ui_
chart
_submit"
)),
column
(
6
,
uiOutput
(
"
ai
_loading"
))
column
(
6
,
uiOutput
(
"
chart
_loading"
))
)
)
),
),
wellPanel
(
wellPanel
(
i
18
n
$
t
(
"Generated R code"
),
i
18
n
$
t
(
"Generated R code"
),
uiOutput
(
"
ai
_r_code_block"
),
uiOutput
(
"
chart
_r_code_block"
),
fluidRow
(
fluidRow
(
column
(
6
,
actionButton
(
"
ai
_run_code"
,
i
18
n
$
t
(
"Run code"
),
icon
=
icon
(
"play"
),
class
=
"btn-success"
)),
column
(
6
,
actionButton
(
"
chart
_run_code"
,
i
18
n
$
t
(
"Run code"
),
icon
=
icon
(
"play"
),
class
=
"btn-success"
)),
column
(
6
,
actionButton
(
"
ai
_edit_code"
,
i
18
n
$
t
(
"Edit code"
),
icon
=
icon
(
"edit"
),
class
=
"btn-default"
))
column
(
6
,
actionButton
(
"
chart
_edit_code"
,
i
18
n
$
t
(
"Edit code"
),
icon
=
icon
(
"edit"
),
class
=
"btn-default"
))
)
)
),
),
help_and_report
(
help_and_report
(
modal_title
=
i
18
n
$
t
(
"AI generates descriptive statistics"
),
modal_title
=
i
18
n
$
t
(
"AI generates descriptive statistics
(chart)
"
),
fun_name
=
"quickgen_
ai
"
,
fun_name
=
"quickgen_
chart
"
,
help_file
=
inclMD
(
file.path
(
getOption
(
"radiant.path.quickgen"
),
"app/tools/help/quickgen_
ai
.md"
)),
help_file
=
inclMD
(
file.path
(
getOption
(
"radiant.path.quickgen"
),
"app/tools/help/quickgen_
chart
.md"
)),
lic
=
"by-sa"
lic
=
"by-sa"
)
)
)
)
})
})
## ==================== 控件渲染 ====================
## ==================== 控件渲染 ====================
output
$
ui_
ai
_submit
<-
renderUI
({
output
$
ui_
chart
_submit
<-
renderUI
({
req
(
input
$
dataset
)
req
(
input
$
dataset
)
actionButton
(
"
ai
_submit"
,
i
18
n
$
t
(
"Send"
),
icon
=
icon
(
"magic"
),
class
=
"btn-primary"
)
actionButton
(
"
chart
_submit"
,
i
18
n
$
t
(
"Send"
),
icon
=
icon
(
"magic"
),
class
=
"btn-primary"
)
})
})
output
$
chart_loading
<-
renderUI
({
output
$
ai_loading
<-
renderUI
({
if
(
isTRUE
(
r_values
$
chart_loading
))
if
(
isTRUE
(
r_values
$
ai_loading
))
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
style
=
"width:100%"
,
style
=
"width:100%"
,
i
18
n
$
t
(
"Calling
AI
model..."
)))
i
18
n
$
t
(
"Calling
chart generation
model..."
)))
})
})
## ==================== reactiveValues ====================
## ==================== reactiveValues ====================
r_values
<-
reactiveValues
(
r_values
<-
reactiveValues
(
ai
_r_code
=
""
,
chart
_r_code
=
""
,
ai
_result_type
=
"text"
,
chart
_result_type
=
"text"
,
ai
_result_ready
=
FALSE
,
chart
_result_ready
=
FALSE
,
ai
_loading
=
FALSE
chart
_loading
=
FALSE
)
)
## ==================== 生成代码 ====================
## ==================== 生成代码 ====================
observeEvent
(
input
$
ai
_submit
,
{
observeEvent
(
input
$
chart
_submit
,
{
if
(
is.empty
(
input
$
ai
_prompt
))
if
(
is.empty
(
input
$
chart
_prompt
))
return
(
showNotification
(
i
18
n
$
t
(
"Please enter an analysis request"
),
type
=
"error"
))
return
(
showNotification
(
i
18
n
$
t
(
"Please enter an analysis request"
),
type
=
"error"
))
r_values
$
ai
_loading
<-
TRUE
r_values
$
chart
_loading
<-
TRUE
shinyjs
::
show
(
"
ai
_progress_box"
)
# 显示右下角进度框
shinyjs
::
show
(
"
chart
_progress_box"
)
# 显示右下角进度框
on.exit
({
on.exit
({
r_values
$
ai
_loading
<-
FALSE
r_values
$
chart
_loading
<-
FALSE
shinyjs
::
hide
(
"
ai
_progress_box"
)
# 无论成功失败都隐藏
shinyjs
::
hide
(
"
chart
_progress_box"
)
# 无论成功失败都隐藏
})
})
res
<-
try
(
do.call
(
ai
_generate
,
res
<-
try
(
do.call
(
chart
_generate
,
list
(
prompt
=
input
$
ai
_prompt
,
list
(
prompt
=
input
$
chart
_prompt
,
dataset
=
input
$
dataset
,
dataset
=
input
$
dataset
,
envir
=
r_data
)),
envir
=
r_data
)),
silent
=
TRUE
)
silent
=
TRUE
)
if
(
inherits
(
res
,
"try-error"
))
{
if
(
inherits
(
res
,
"try-error"
))
{
showNotification
(
paste
(
i
18
n
$
t
(
"
AI
API error:"
),
res
),
type
=
"error"
)
showNotification
(
paste
(
i
18
n
$
t
(
"
Chart
API error:"
),
res
),
type
=
"error"
)
return
()
return
()
}
}
r_values
$
ai
_r_code
<-
res
$
r_code
r_values
$
chart
_r_code
<-
res
$
r_code
r_values
$
ai
_result_type
<-
res
$
type
r_values
$
chart
_result_type
<-
res
$
type
r_values
$
ai
_result_ready
<-
FALSE
r_values
$
chart
_result_ready
<-
FALSE
r_values
$
auto_run
<-
res
$
auto_run
r_values
$
auto_run
<-
res
$
auto_run
if
(
res
$
type
==
"empty"
)
{
if
(
res
$
type
==
"empty"
)
{
shinyjs
::
show
(
"
ai
_warn_box"
)
shinyjs
::
show
(
"
chart
_warn_box"
)
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"
ai
_warn_box"
))
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"
chart
_warn_box"
))
return
()
return
()
}
}
if
(
isTRUE
(
r_values
$
auto_run
))
if
(
isTRUE
(
r_values
$
auto_run
))
shinyjs
::
click
(
"
ai
_run_code"
)
shinyjs
::
click
(
"
chart
_run_code"
)
})
})
## ==================== 显示 R 代码 ====================
## ==================== 显示 R 代码 ====================
output
$
ai
_r_code_block
<-
renderUI
({
output
$
chart
_r_code_block
<-
renderUI
({
codes
<-
r_values
$
ai
_r_code
codes
<-
r_values
$
chart
_r_code
tags
$
pre
(
codes
,
style
=
"background:#f5f5f5; padding:10px; border-radius:4px;
tags
$
pre
(
codes
,
style
=
"background:#f5f5f5; padding:10px; border-radius:4px;
font-family:monospace; white-space:pre-wrap; min-height:100px;"
)
font-family:monospace; white-space:pre-wrap; min-height:100px;"
)
})
})
## ==================== 运行代码 ====================
## ==================== 运行代码 ====================
observeEvent
(
input
$
ai
_run_code
,
{
observeEvent
(
input
$
chart
_run_code
,
{
shinyjs
::
hide
(
"
ai
_progress_box"
)
shinyjs
::
hide
(
"
chart
_progress_box"
)
if
(
is.empty
(
r_values
$
ai
_r_code
))
return
()
if
(
is.empty
(
r_values
$
chart
_r_code
))
return
()
if
(
trimws
(
r_values
$
ai_r_code
)
==
""
||
identical
(
r_values
$
ai
_result_type
,
"empty"
))
{
if
(
trimws
(
r_values
$
chart_r_code
)
==
""
||
identical
(
r_values
$
chart
_result_type
,
"empty"
))
{
shinyjs
::
show
(
"
ai
_warn_box"
)
shinyjs
::
show
(
"
chart
_warn_box"
)
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"
ai
_warn_box"
))
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"
chart
_warn_box"
))
return
()
return
()
}
}
tryCatch
({
tryCatch
({
result
<-
do.call
(
ai
_run_code
,
result
<-
do.call
(
chart
_run_code
,
list
(
r_code
=
r_values
$
ai
_r_code
,
envir
=
r_data
))
list
(
r_code
=
r_values
$
chart
_r_code
,
envir
=
r_data
))
r_data
$
ai
_temp_result
<-
result
r_data
$
chart
_temp_result
<-
result
if
(
inherits
(
result
,
"gg"
)
||
inherits
(
result
,
"ggplot"
))
{
if
(
inherits
(
result
,
"gg"
)
||
inherits
(
result
,
"ggplot"
))
{
r_values
$
ai
_result_type
<-
"plot"
r_values
$
chart
_result_type
<-
"plot"
output
$
ai
_result_plot
<-
renderPlot
(
print
(
result
))
output
$
chart
_result_plot
<-
renderPlot
(
print
(
result
))
}
else
if
(
is.data.frame
(
result
)
||
is.matrix
(
result
))
{
}
else
if
(
is.data.frame
(
result
)
||
is.matrix
(
result
))
{
r_values
$
ai
_result_type
<-
"table"
r_values
$
chart
_result_type
<-
"table"
output
$
ai
_result_table
<-
DT
::
renderDataTable
(
output
$
chart
_result_table
<-
DT
::
renderDataTable
(
DT
::
datatable
(
result
,
options
=
list
(
scrollX
=
TRUE
,
pageLength
=
10
)))
DT
::
datatable
(
result
,
options
=
list
(
scrollX
=
TRUE
,
pageLength
=
10
)))
}
else
{
}
else
{
r_values
$
ai
_result_type
<-
"text"
r_values
$
chart
_result_type
<-
"text"
output
$
ai
_result_text
<-
renderText
(
capture.output
(
print
(
result
)))
output
$
chart
_result_text
<-
renderText
(
capture.output
(
print
(
result
)))
}
}
r_values
$
ai
_result_ready
<-
TRUE
r_values
$
chart
_result_ready
<-
TRUE
},
error
=
function
(
e
)
{
},
error
=
function
(
e
)
{
r_values
$
ai
_result_type
<-
"error"
r_values
$
chart
_result_type
<-
"error"
output
$
ai
_result_error
<-
renderText
(
paste0
(
i
18
n
$
t
(
"Error: "
),
e
$
message
))
output
$
chart
_result_error
<-
renderText
(
paste0
(
i
18
n
$
t
(
"Error: "
),
e
$
message
))
r_values
$
ai
_result_ready
<-
TRUE
r_values
$
chart
_result_ready
<-
TRUE
showNotification
(
paste0
(
i
18
n
$
t
(
"Run code error: "
),
e
$
message
),
showNotification
(
paste0
(
i
18
n
$
t
(
"Run code error: "
),
e
$
message
),
type
=
"error"
,
duration
=
NULL
)
type
=
"error"
,
duration
=
NULL
)
})
})
},
ignoreInit
=
TRUE
)
},
ignoreInit
=
TRUE
)
## ======== 结果展示区========
## ======== 结果展示区========
output
$
ai
_result_area
<-
renderUI
({
output
$
chart
_result_area
<-
renderUI
({
req
(
r_values
$
ai
_result_ready
)
req
(
r_values
$
chart
_result_ready
)
tagList
(
tagList
(
conditionalPanel
(
conditionalPanel
(
condition
=
"output.
ai
_result_type == 'plot'"
,
condition
=
"output.
chart
_result_type == 'plot'"
,
download_link
(
"dlp_
ai
_plot"
),
br
(),
download_link
(
"dlp_
chart
_plot"
),
br
(),
plotOutput
(
"
ai
_result_plot"
,
width
=
"100%"
,
height
=
"500px"
)
plotOutput
(
"
chart
_result_plot"
,
width
=
"100%"
,
height
=
"500px"
)
),
),
conditionalPanel
(
conditionalPanel
(
condition
=
"output.
ai
_result_type == 'table'"
,
condition
=
"output.
chart
_result_type == 'table'"
,
download_link
(
"dlp_
ai
_table"
),
br
(),
download_link
(
"dlp_
chart
_table"
),
br
(),
DT
::
dataTableOutput
(
"
ai
_result_table"
)
DT
::
dataTableOutput
(
"
chart
_result_table"
)
),
),
conditionalPanel
(
conditionalPanel
(
condition
=
"output.
ai_result_type == 'text' || output.ai
_result_type == 'error'"
,
condition
=
"output.
chart_result_type == 'text' || output.chart
_result_type == 'error'"
,
verbatimTextOutput
(
"
ai
_result_text"
)
verbatimTextOutput
(
"
chart
_result_text"
)
)
)
)
)
})
})
output
$
chart_result_type
<-
reactive
({
r_values
$
chart_result_type
output
$
ai_result_type
<-
reactive
({
r_values
$
ai_result_type
})
})
outputOptions
(
output
,
"chart_result_type"
,
suspendWhenHidden
=
FALSE
)
outputOptions
(
output
,
"ai_result_type"
,
suspendWhenHidden
=
FALSE
)
## ==================== 编辑代码模态框 ====================
## ==================== 编辑代码模态框 ====================
observeEvent
(
input
$
ai
_edit_code
,
{
observeEvent
(
input
$
chart
_edit_code
,
{
showModal
(
showModal
(
modalDialog
(
modalDialog
(
title
=
i
18
n
$
t
(
"Edit R Code"
),
title
=
i
18
n
$
t
(
"Edit R Code"
),
size
=
"l"
,
size
=
"l"
,
footer
=
tagList
(
footer
=
tagList
(
actionButton
(
"
ai
_save_code"
,
i
18
n
$
t
(
"Save Changes"
),
class
=
"btn-primary"
),
actionButton
(
"
chart
_save_code"
,
i
18
n
$
t
(
"Save Changes"
),
class
=
"btn-primary"
),
modalButton
(
i
18
n
$
t
(
"Cancel"
))
modalButton
(
i
18
n
$
t
(
"Cancel"
))
),
),
aceEditor
(
aceEditor
(
"
ai
_code_editor"
,
"
chart
_code_editor"
,
mode
=
"r"
,
mode
=
"r"
,
theme
=
getOption
(
"radiant.ace_theme"
,
"tomorrow"
),
theme
=
getOption
(
"radiant.ace_theme"
,
"tomorrow"
),
wordWrap
=
TRUE
,
wordWrap
=
TRUE
,
value
=
r_values
$
ai
_r_code
,
value
=
r_values
$
chart
_r_code
,
placeholder
=
i
18
n
$
t
(
"Edit the generated R code here..."
),
placeholder
=
i
18
n
$
t
(
"Edit the generated R code here..."
),
vimKeyBinding
=
getOption
(
"radiant.ace_vim.keys"
,
FALSE
),
vimKeyBinding
=
getOption
(
"radiant.ace_vim.keys"
,
FALSE
),
tabSize
=
getOption
(
"radiant.ace_tabSize"
,
2
),
tabSize
=
getOption
(
"radiant.ace_tabSize"
,
2
),
...
@@ -243,15 +239,15 @@ observeEvent(input$ai_edit_code, {
...
@@ -243,15 +239,15 @@ observeEvent(input$ai_edit_code, {
})
})
## ==================== 保存代码 ====================
## ==================== 保存代码 ====================
observeEvent
(
input
$
ai
_save_code
,
{
observeEvent
(
input
$
chart
_save_code
,
{
r_values
$
ai_r_code
<-
input
$
ai
_code_editor
r_values
$
chart_r_code
<-
input
$
chart
_code_editor
r_values
$
auto_run
<-
FALSE
r_values
$
auto_run
<-
FALSE
removeModal
()
removeModal
()
})
})
## ==================== PNG 下载处理器 ====================
## ==================== PNG 下载处理器 ====================
dlp_
ai
_plot
<-
function
(
path
)
{
dlp_
chart
_plot
<-
function
(
path
)
{
result
<-
r_data
$
ai
_temp_result
result
<-
r_data
$
chart
_temp_result
if
(
inherits
(
result
,
"gg"
)
||
inherits
(
result
,
"ggplot"
))
{
if
(
inherits
(
result
,
"gg"
)
||
inherits
(
result
,
"ggplot"
))
{
png
(
path
,
width
=
800
,
height
=
500
,
res
=
96
)
png
(
path
,
width
=
800
,
height
=
500
,
res
=
96
)
print
(
result
)
print
(
result
)
...
@@ -263,33 +259,44 @@ dlp_ai_plot <- function(path) {
...
@@ -263,33 +259,44 @@ dlp_ai_plot <- function(path) {
dev.off
()
dev.off
()
}
}
}
}
download_handler
(
download_handler
(
id
=
"dlp_
ai
_plot"
,
id
=
"dlp_
chart
_plot"
,
fun
=
dlp_
ai
_plot
,
fun
=
dlp_
chart
_plot
,
fn
=
function
()
paste0
(
"plot_"
,
Sys.Date
()),
fn
=
function
()
paste0
(
"plot_"
,
Sys.Date
()),
type
=
"png"
,
type
=
"png"
,
caption
=
i
18
n
$
t
(
"Save
AI
-generated plot"
)
caption
=
i
18
n
$
t
(
"Save
chart
-generated plot"
)
)
)
# ======== 表格 CSV 下载处理器 ========
# ======== 表格 CSV 下载处理器 ========
dlp_
ai
_table
<-
function
(
path
)
{
dlp_
chart
_table
<-
function
(
path
)
{
result
<-
r_data
$
ai
_temp_result
result
<-
r_data
$
chart
_temp_result
if
(
is.data.frame
(
result
))
{
if
(
is.data.frame
(
result
))
{
write.csv
(
result
,
file
=
path
,
row.names
=
FALSE
)
df
<-
result
}
else
if
(
is.table
(
result
))
{
df
<-
as.data.frame
(
result
,
stringsAsFactors
=
FALSE
)
}
else
if
(
is.matrix
(
result
))
{
df
<-
as.data.frame
(
result
,
stringsAsFactors
=
FALSE
)
if
(
!
is.null
(
rownames
(
result
)))
{
df
<-
cbind
(
row_name
=
rownames
(
result
),
df
,
row.names
=
NULL
)
}
}
else
{
}
else
{
write.csv
(
data.frame
(
msg
=
"No table available"
),
file
=
path
,
row.names
=
FALSE
)
df
<-
data.frame
(
msg
=
"No valid table available"
)
}
}
write.csv
(
df
,
file
=
path
,
row.names
=
FALSE
,
fileEncoding
=
"UTF-8"
)
}
}
download_handler
(
download_handler
(
id
=
"dlp_
ai
_table"
,
id
=
"dlp_
chart
_table"
,
fun
=
dlp_
ai
_table
,
fun
=
dlp_
chart
_table
,
fn
=
function
()
paste0
(
"table_"
,
Sys.Date
()),
fn
=
function
()
paste0
(
"table_"
,
Sys.Date
()),
type
=
"csv"
,
type
=
"csv"
,
caption
=
i
18
n
$
t
(
"Save
AI
-generated table"
)
caption
=
i
18
n
$
t
(
"Save
chart
-generated table"
)
)
)
## ==================== 报告 / 截图 ====================
## ==================== 报告 / 截图 ====================
ai_report
<-
function
()
{}
chart_report
<-
function
()
{}
observeEvent
(
input
$
ai_report
,
ai_report
())
observeEvent
(
input
$
chart_report
,
chart_report
())
observeEvent
(
input
$
ai_screenshot
,
radiant_screenshot_modal
(
"modal_ai_screenshot"
))
observeEvent
(
input
$
chart_screenshot
,
radiant_screenshot_modal
(
"modal_chart_screenshot"
))
observeEvent
(
input
$
modal_ai_screenshot
,
{
ai_report
();
removeModal
()
})
observeEvent
(
input
$
modal_chart_screenshot
,
{
chart_report
();
removeModal
()
})
\ No newline at end of file
radiant.quickgen/inst/app/tools/analysis/quickgen_chat_ui.R
View file @
f261dcec
...
@@ -6,7 +6,7 @@ output$quickgen_chat <- renderUI({
...
@@ -6,7 +6,7 @@ output$quickgen_chat <- renderUI({
tagList
(
tagList
(
useShinyjs
(),
useShinyjs
(),
stat_tab_panel
(
stat_tab_panel
(
menu
=
i
18
n
$
t
(
"One
-click generation > AI chat guid
ance"
),
menu
=
i
18
n
$
t
(
"One
click generation > AI assist
ance"
),
tool
=
i
18
n
$
t
(
"AI chat guidance"
),
tool
=
i
18
n
$
t
(
"AI chat guidance"
),
tool_ui
=
"chat_main_ui"
,
tool_ui
=
"chat_main_ui"
,
output_panels
=
tabPanel
(
output_panels
=
tabPanel
(
...
...
radiant.quickgen/inst/app/tools/analysis/quickgen_metrics_ui.R
0 → 100644
View file @
f261dcec
# quickgen_metrics_ui.R
library
(
shinyjs
)
library
(
shinyAce
)
# 新增:统计结果文本格式化函数
format_stat_text
<-
function
(
result
,
dataset_name
)
{
# 1. 处理“无法计算”的情况
if
(
is.character
(
result
)
&&
grepl
(
"无法计算"
,
result
))
{
return
(
result
)
}
# 2. 单样本t检验(htest类)
if
(
inherits
(
result
,
"htest"
)
&&
grepl
(
"One Sample t-test"
,
result
$
method
))
{
# 提取关键指标
var_name
<-
gsub
(
"^x = df\\$|^df\\$"
,
""
,
as.character
(
result
$
data.name
))
mean_val
<-
round
(
mean
(
result
$
data
,
na.rm
=
TRUE
),
3
)
n_val
<-
length
(
na.omit
(
result
$
data
))
n_missing
<-
sum
(
is.na
(
result
$
data
))
sd_val
<-
round
(
sd
(
result
$
data
,
na.rm
=
TRUE
),
3
)
se_val
<-
round
(
result
$
stderr
,
3
)
me_val
<-
round
(
se_val
*
qt
(
0.975
,
df
=
result
$
parameter
),
3
)
# 边际误差
diff_val
<-
round
(
result
$
estimate
,
3
)
t_val
<-
round
(
result
$
statistic
,
3
)
p_val
<-
if
(
result
$
p.value
<
0.001
)
"< .001"
else
round
(
result
$
p.value
,
4
)
df_val
<-
result
$
parameter
ci_lower
<-
round
(
result
$
conf.int
[
1
],
3
)
ci_upper
<-
round
(
result
$
conf.int
[
2
],
3
)
conf_level
<-
round
(
attr
(
result
$
conf.int
,
"conf.level"
)
*
100
,
1
)
# 显著性标记
signif
<-
if
(
p_val
==
"< .001"
)
"***"
else
if
(
p_val
<=
0.001
)
"***"
else
if
(
p_val
<=
0.01
)
"**"
else
if
(
p_val
<=
0.05
)
"*"
else
if
(
p_val
<=
0.1
)
"."
else
" "
# 组织文本(完全匹配示例格式)
text
<-
sprintf
(
paste0
(
"Single mean test\n"
,
"Data : %s \n"
,
"Variable : %s \n"
,
"Confidence: %.1f%% \n"
,
"Null hyp. : the mean of %s = %.1f \n"
,
"Alt. hyp. : the mean of %s is not equal to %.1f \n"
,
" mean n n_missing sd se me\n"
,
" %6.3f %5s %d %6.3f %5.3f %5.3f\n"
,
" diff se t.value p.value df 2.5%% 97.5%% \n"
,
" %6.3f %5.3f %6.3f %8s %5.0f %6.3f %6.3f %s\n"
,
"Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1"
),
dataset_name
,
var_name
,
conf_level
,
var_name
,
result
$
null.value
,
var_name
,
result
$
null.value
,
mean_val
,
format
(
n_val
,
big.mark
=
","
),
n_missing
,
sd_val
,
se_val
,
me_val
,
diff_val
,
se_val
,
t_val
,
p_val
,
df_val
,
ci_lower
,
ci_upper
,
signif
)
return
(
text
)
}
# 3. 独立样本t检验(htest类)
if
(
inherits
(
result
,
"htest"
)
&&
grepl
(
"Welch Two Sample t-test|Two Sample t-test"
,
result
$
method
))
{
# 提取分组变量和数值变量
data_parts
<-
strsplit
(
result
$
data.name
,
" ~ "
)[[
1
]]
var_name
<-
data_parts
[
1
]
group_var
<-
data_parts
[
2
]
group_vals
<-
levels
(
factor
(
df
[[
group_var
]]))
# 分组统计
group1_data
<-
df
[[
var_name
]][
df
[[
group_var
]]
==
group_vals
[
1
]]
group2_data
<-
df
[[
var_name
]][
df
[[
group_var
]]
==
group_vals
[
2
]]
mean1
<-
round
(
mean
(
group1_data
,
na.rm
=
TRUE
),
3
)
mean2
<-
round
(
mean
(
group2_data
,
na.rm
=
TRUE
),
3
)
n
1
<-
length
(
na.omit
(
group1_data
))
n
2
<-
length
(
na.omit
(
group2_data
))
n_missing1
<-
sum
(
is.na
(
group1_data
))
n_missing2
<-
sum
(
is.na
(
group2_data
))
sd1
<-
round
(
sd
(
group1_data
,
na.rm
=
TRUE
),
3
)
sd2
<-
round
(
sd
(
group2_data
,
na.rm
=
TRUE
),
3
)
se1
<-
round
(
sd1
/
sqrt
(
n
1
),
3
)
se2
<-
round
(
sd2
/
sqrt
(
n
2
),
3
)
me1
<-
round
(
se1
*
qt
(
0.975
,
df
=
n
1
-
1
),
3
)
me2
<-
round
(
se2
*
qt
(
0.975
,
df
=
n
2
-
1
),
3
)
# 检验结果
diff_val
<-
round
(
result
$
estimate
[
1
]
-
result
$
estimate
[
2
],
3
)
t_val
<-
round
(
result
$
statistic
,
3
)
p_val
<-
if
(
result
$
p.value
<
0.001
)
"< .001"
else
round
(
result
$
p.value
,
4
)
df_val
<-
round
(
result
$
parameter
,
0
)
ci_lower
<-
round
(
result
$
conf.int
[
1
],
3
)
ci_upper
<-
round
(
result
$
conf.int
[
2
],
3
)
conf_level
<-
round
(
attr
(
result
$
conf.int
,
"conf.level"
)
*
100
,
1
)
signif
<-
if
(
p_val
==
"< .001"
)
"***"
else
if
(
p_val
<=
0.001
)
"***"
else
if
(
p_val
<=
0.01
)
"**"
else
if
(
p_val
<=
0.05
)
"*"
else
if
(
p_val
<=
0.1
)
"."
else
" "
# 组织文本
text
<-
sprintf
(
paste0
(
"Pairwise mean comparisons (t-test)\n"
,
"Data : %s \n"
,
"Variables : %s, %s \n"
,
"Samples : independent \n"
,
"Confidence: %.1f%% \n"
,
"Adjustment: None \n"
,
" mean n n_missing sd se me\n"
,
" %6s %6.3f %5s %d %6.3f %5.3f %5.3f\n"
,
" %6s %6.3f %5s %d %6.3f %5.3f %5.3f\n"
,
" Null hyp. Alt. hyp. diff p.value \n"
,
" %s = %s %s not equal to %s %6.3f %8s %s\n"
,
"Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1"
),
dataset_name
,
group_var
,
var_name
,
conf_level
,
group_vals
[
1
],
mean1
,
format
(
n
1
,
big.mark
=
","
),
n_missing1
,
sd1
,
se1
,
me1
,
group_vals
[
2
],
mean2
,
format
(
n
2
,
big.mark
=
","
),
n_missing2
,
sd2
,
se2
,
me2
,
group_vals
[
1
],
group_vals
[
2
],
group_vals
[
1
],
group_vals
[
2
],
diff_val
,
p_val
,
signif
)
return
(
text
)
}
# 4. 线性回归(lm类)
if
(
inherits
(
result
,
"lm"
))
{
# 提取模型信息
model_formula
<-
as.character
(
result
$
call
$
formula
)
var_dep
<-
model_formula
[
2
]
vars_indep
<-
gsub
(
"^ ~ "
,
""
,
model_formula
[
1
])
# 系数表
coef_sum
<-
summary
(
result
)
$
coefficients
coef_text
<-
" Estimate Std.Error t.value p.value Signif.\n"
for
(
i
in
1
:
nrow
(
coef_sum
))
{
term
<-
rownames
(
coef_sum
)[
i
]
est
<-
round
(
coef_sum
[
i
,
1
],
4
)
se
<-
round
(
coef_sum
[
i
,
2
],
4
)
t_val
<-
round
(
coef_sum
[
i
,
3
],
3
)
p_val
<-
if
(
coef_sum
[
i
,
4
]
<
0.001
)
"< .001"
else
round
(
coef_sum
[
i
,
4
],
4
)
signif
<-
if
(
p_val
==
"< .001"
)
"***"
else
if
(
p_val
<=
0.001
)
"***"
else
if
(
p_val
<=
0.01
)
"**"
else
if
(
p_val
<=
0.05
)
"*"
else
if
(
p_val
<=
0.1
)
"."
else
" "
coef_text
<-
paste0
(
coef_text
,
sprintf
(
" %12s %8.4f %8.4f %6.3f %8s %3s\n"
,
term
,
est
,
se
,
t_val
,
p_val
,
signif
))
}
# 模型拟合度
r
2
<-
round
(
summary
(
result
)
$
r.squared
,
4
)
r
2
_
adj
<-
round
(
summary
(
result
)
$
adj.r.squared
,
4
)
n_val
<-
nrow
(
result
$
model
)
n_missing
<-
nrow
(
df
)
-
n_val
# 组织文本
text
<-
sprintf
(
paste0
(
"Linear Regression Model\n"
,
"Data : %s \n"
,
"Formula : %s ~ %s \n"
,
"Dependent : %s \n"
,
"Independent: %s \n"
,
"Sample : n = %s, n_missing = %d \n"
,
"Fit : R² = %.4f, Adjusted R² = %.4f \n"
,
"%s"
,
"Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1"
),
dataset_name
,
var_dep
,
vars_indep
,
var_dep
,
vars_indep
,
format
(
n_val
,
big.mark
=
","
),
n_missing
,
r
2
,
r
2
_
adj
,
coef_text
)
return
(
text
)
}
# 5. 其他统计方法(卡方检验、方差分析等,按示例风格扩展)
if
(
inherits
(
result
,
"htest"
)
&&
grepl
(
"Chi-squared test"
,
result
$
method
))
{
# 卡方检验文本格式化(类似逻辑,提取列联表、卡方值、p值等)
data_parts
<-
strsplit
(
result
$
data.name
,
" ~ "
)[[
1
]]
var1
<-
data_parts
[
1
]
var2
<-
data_parts
[
2
]
contingency
<-
table
(
df
[[
var1
]],
df
[[
var2
]],
useNA
=
"no"
)
chi_val
<-
round
(
result
$
statistic
,
3
)
df_val
<-
result
$
parameter
p_val
<-
if
(
result
$
p.value
<
0.001
)
"< .001"
else
round
(
result
$
p.value
,
4
)
signif
<-
if
(
p_val
==
"< .001"
)
"***"
else
if
(
p_val
<=
0.001
)
"***"
else
if
(
p_val
<=
0.01
)
"**"
else
if
(
p_val
<=
0.05
)
"*"
else
if
(
p_val
<=
0.1
)
"."
else
" "
text
<-
sprintf
(
paste0
(
"Chi-squared Test of Independence\n"
,
"Data : %s \n"
,
"Variables : %s (row), %s (column) \n"
,
"Contingency Table:\n%s\n"
,
"Test Statistic: Chi-squared = %.3f, df = %.0f, p-value = %s %s\n"
,
"Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1"
),
dataset_name
,
var1
,
var2
,
capture.output
(
print
(
contingency
)),
chi_val
,
df_val
,
p_val
,
signif
)
return
(
text
)
}
# 6. 直接输出原始结果
return
(
capture.output
(
print
(
result
)))
}
## ==================== 右下角浮框 ====================
ui_metrics_progress
<-
tags
$
div
(
id
=
"metrics_progress_box"
,
style
=
"display:none;
position:fixed;
bottom:15px; right:15px;
width:220px; z-index:9999;
background:#f5f5f5; color:#333;
border:1px solid #337ab7; border-radius:4px;
padding:10px 15px; box-shadow:0 2px 8px rgba(0,0,0,.25);"
,
tags
$
strong
(
i
18
n
$
t
(
"AI calculating..."
)),
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
style
=
"width:100%"
))
)
## ======== 警告弹窗========
ui_metrics_warn
<-
tags
$
div
(
id
=
"metrics_warn_box"
,
style
=
"display:none;
position:fixed;
bottom:15px; right:15px;
width:220px; z-index:9999;
background:#fff3cd; color:#856404;
border:1px solid #ffeaa7; border-radius:4px;
padding:10px 15px; box-shadow:0 2px 8px rgba(0,0,0,.25);"
,
tags
$
strong
(
i
18
n
$
t
(
"Warning:Please enter a request related to scientific research statistical calculation."
))
)
## ==================== 统一入口 ====================
output
$
quickgen_metrics
<-
renderUI
({
stat_tab_panel
(
menu
=
i
18
n
$
t
(
"Oneclick generation > AI assistance"
),
tool
=
i
18
n
$
t
(
"AI generates descriptive statistics(metrics)"
),
tool_ui
=
"metrics_main_ui"
,
output_panels
=
tabPanel
(
title
=
i
18
n
$
t
(
"Metrics Assistant"
),
value
=
"metrics_panel"
,
uiOutput
(
"metrics_result_area"
)
)
)
})
## ==================== 右侧 Metrics 面板 ====================
output
$
metrics_main_ui
<-
renderUI
({
tagList
(
useShinyjs
(),
ui_metrics_progress
,
ui_metrics_warn
,
wellPanel
(
i
18
n
$
t
(
"Describe your analysis request:"
),
returnTextAreaInput
(
"metrics_prompt"
,
label
=
NULL
,
placeholder
=
i
18
n
$
t
(
"e. g. 1. Single mean test for age (null mean=35) in insurance; 2. Chi-squared test between sex and smoker; 3. Linear regression of charges on bmi+age"
),
rows
=
4
,
value
=
state_init
(
"metrics_prompt"
,
""
)),
fluidRow
(
column
(
6
,
uiOutput
(
"ui_metrics_submit"
)),
column
(
6
,
uiOutput
(
"metrics_loading"
))
)
),
wellPanel
(
i
18
n
$
t
(
"Generated R code"
),
uiOutput
(
"metrics_r_code_block"
),
fluidRow
(
column
(
6
,
actionButton
(
"metrics_run_code"
,
i
18
n
$
t
(
"Run code"
),
icon
=
icon
(
"play"
),
class
=
"btn-success"
)),
column
(
6
,
actionButton
(
"metrics_edit_code"
,
i
18
n
$
t
(
"Edit code"
),
icon
=
icon
(
"edit"
),
class
=
"btn-default"
))
)
),
help_and_report
(
modal_title
=
i
18
n
$
t
(
"AI generates descriptive statistics(metrics)"
),
fun_name
=
"quickgen_metrics"
,
help_file
=
inclMD
(
file.path
(
getOption
(
"radiant.path.quickgen"
),
"app/tools/help/quickgen_metrics.md"
)),
lic
=
"by-sa"
)
)
})
## ==================== 控件渲染 ====================
output
$
ui_metrics_submit
<-
renderUI
({
req
(
input
$
dataset
)
actionButton
(
"metrics_submit"
,
i
18
n
$
t
(
"Send"
),
icon
=
icon
(
"magic"
),
class
=
"btn-primary"
)
})
output
$
metrics_loading
<-
renderUI
({
if
(
isTRUE
(
r_values
$
metrics_loading
))
tags
$
div
(
class
=
"progress"
,
tags
$
div
(
class
=
"progress-bar progress-bar-striped active"
,
style
=
"width:100%"
,
i
18
n
$
t
(
"Calling metrics calculation model..."
)))
})
## ==================== reactiveValues ====================
r_values
<-
reactiveValues
(
metrics_r_code
=
""
,
metrics_result_type
=
"text"
,
# 仅保留text/plot/error
metrics_result_ready
=
FALSE
,
metrics_loading
=
FALSE
)
## ==================== 生成代码 ====================
observeEvent
(
input
$
metrics_submit
,
{
if
(
is.empty
(
input
$
metrics_prompt
))
return
(
showNotification
(
i
18
n
$
t
(
"Please enter a statistical calculation request"
),
type
=
"error"
))
r_values
$
metrics_loading
<-
TRUE
shinyjs
::
show
(
"metrics_progress_box"
)
# 显示右下角进度框
on.exit
({
r_values
$
metrics_loading
<-
FALSE
shinyjs
::
hide
(
"metrics_progress_box"
)
# 无论成功失败都隐藏
})
res
<-
try
(
do.call
(
metrics_generate
,
list
(
prompt
=
input
$
metrics_prompt
,
dataset
=
input
$
dataset
,
envir
=
r_data
)),
silent
=
TRUE
)
if
(
inherits
(
res
,
"try-error"
))
{
showNotification
(
paste
(
i
18
n
$
t
(
"Metrics API error:"
),
res
),
type
=
"error"
)
return
()
}
r_values
$
metrics_r_code
<-
res
$
r_code
r_values
$
metrics_result_type
<-
res
$
type
r_values
$
metrics_result_ready
<-
FALSE
r_values
$
auto_run
<-
res
$
auto_run
if
(
res
$
type
==
"empty"
)
{
shinyjs
::
show
(
"metrics_warn_box"
)
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"metrics_warn_box"
))
return
()
}
if
(
isTRUE
(
r_values
$
auto_run
))
shinyjs
::
click
(
"metrics_run_code"
)
})
## ==================== 显示 R 代码 ====================
output
$
metrics_r_code_block
<-
renderUI
({
codes
<-
r_values
$
metrics_r_code
tags
$
pre
(
codes
,
style
=
"background:#f5f5f5; padding:10px; border-radius:4px;
font-family:monospace; white-space:pre-wrap; min-height:100px;"
)
})
## ==================== 运行代码 ====================
observeEvent
(
input
$
metrics_run_code
,
{
shinyjs
::
hide
(
"metrics_progress_box"
)
if
(
is.empty
(
r_values
$
metrics_r_code
))
return
()
if
(
trimws
(
r_values
$
metrics_r_code
)
==
""
||
identical
(
r_values
$
metrics_result_type
,
"empty"
))
{
shinyjs
::
show
(
"metrics_warn_box"
)
shinyjs
::
delay
(
3000
,
shinyjs
::
hide
(
"metrics_warn_box"
))
return
()
}
tryCatch
({
# 执行代码并获取原始结果
result
<-
do.call
(
metrics_run_code
,
list
(
r_code
=
r_values
$
metrics_r_code
,
envir
=
r_data
))
r_data
$
metrics_temp_result
<-
result
dataset_name
<-
input
$
dataset
# 获取当前数据集名称
# 分支1:屏蔽图表输出
if
(
inherits
(
result
,
"gg"
)
||
inherits
(
result
,
"ggplot"
)
||
inherits
(
result
,
"lattice"
))
{
r_values
$
metrics_result_type
<-
"text"
output
$
metrics_result_text
<-
renderText
(
i
18
n
$
t
(
"This tool only supports statistical metrics calculation, not chart generation"
))
}
# 分支2:所有统计结果转为结构化文本
else
{
r_values
$
metrics_result_type
<-
"text"
# 调用格式化函数,生成示例风格的文本
formatted_text
<-
format_stat_text
(
result
,
dataset_name
)
# 输出文本(保留换行和空格对齐)
output
$
metrics_result_text
<-
renderText
(
paste
(
formatted_text
,
collapse
=
"\n"
))
}
r_values
$
metrics_result_ready
<-
TRUE
},
error
=
function
(
e
)
{
r_values
$
metrics_result_type
<-
"error"
# 错误文本格式化
err_msg
<-
if
(
grepl
(
"object .* not found"
,
e
$
message
))
{
paste0
(
i
18
n
$
t
(
"Error: Target column does not exist - "
),
e
$
message
)
}
else
if
(
grepl
(
"non-numeric argument"
,
e
$
message
))
{
paste0
(
i
18
n
$
t
(
"Error: Variable type mismatch (e.g., t-test requires numeric variables) - "
),
e
$
message
)
}
else
{
paste0
(
i
18
n
$
t
(
"Error: "
),
e
$
message
)
}
output
$
metrics_result_error
<-
renderText
(
err_msg
)
r_values
$
metrics_result_ready
<-
TRUE
showNotification
(
err_msg
,
type
=
"error"
,
duration
=
NULL
)
})
},
ignoreInit
=
TRUE
)
## ======== 结果展示区(仅文本/错误输出)========
output
$
metrics_result_area
<-
renderUI
({
req
(
r_values
$
metrics_result_ready
)
tagList
(
# 所有结果均用文本框展示(含图表屏蔽提示、统计结果、错误)
conditionalPanel
(
condition
=
"output.metrics_result_type == 'text' || output.metrics_result_type == 'error'"
,
verbatimTextOutput
(
"metrics_result_text"
,
placeholder
=
TRUE
)
)
)
})
output
$
metrics_result_type
<-
reactive
({
r_values
$
metrics_result_type
})
outputOptions
(
output
,
"metrics_result_type"
,
suspendWhenHidden
=
FALSE
)
## ==================== 编辑代码模态框 ====================
observeEvent
(
input
$
metrics_edit_code
,
{
showModal
(
modalDialog
(
title
=
i
18
n
$
t
(
"Edit R Code"
),
size
=
"l"
,
footer
=
tagList
(
actionButton
(
"metrics_save_code"
,
i
18
n
$
t
(
"Save Changes"
),
class
=
"btn-primary"
),
modalButton
(
i
18
n
$
t
(
"Cancel"
))
),
aceEditor
(
"metrics_code_editor"
,
mode
=
"r"
,
theme
=
getOption
(
"radiant.ace_theme"
,
"tomorrow"
),
wordWrap
=
TRUE
,
value
=
r_values
$
metrics_r_code
,
placeholder
=
i
18
n
$
t
(
"Edit the generated R code here..."
),
vimKeyBinding
=
getOption
(
"radiant.ace_vim.keys"
,
FALSE
),
tabSize
=
getOption
(
"radiant.ace_tabSize"
,
2
),
useSoftTabs
=
getOption
(
"radiant.ace_useSoftTabs"
,
TRUE
),
showInvisibles
=
getOption
(
"radiant.ace_showInvisibles"
,
FALSE
),
autoScrollEditorIntoView
=
TRUE
,
minLines
=
15
,
maxLines
=
30
)
)
)
})
## ==================== 保存代码 ====================
observeEvent
(
input
$
metrics_save_code
,
{
r_values
$
metrics_r_code
<-
input
$
metrics_code_editor
r_values
$
auto_run
<-
FALSE
removeModal
()
})
## ==================== 报告 / 截图 ====================
metrics_report
<-
function
()
{}
observeEvent
(
input
$
metrics_report
,
metrics_report
())
observeEvent
(
input
$
metrics_screenshot
,
radiant_screenshot_modal
(
"modal_metrics_screenshot"
))
observeEvent
(
input
$
modal_metrics_screenshot
,
{
metrics_report
();
removeModal
()
})
radiant.quickgen/inst/app/tools/help/quickgen_ai.md
deleted
100644 → 0
View file @
b3e914bc
> 大模型生成描述性统计
## 使用方法
以下是
`大模型生成描述性统计`
的使用方法。
1.
`数据对象`
必须要有,且必须和数据集中的名字一致(大小写也一致)
2.
`图像类型`
必须要有,比如分布图、散点图等。可以要求模型返回多张图表,需向模型明确。
3.
`生成代码`
如果有误,或者想要修改,可以点击
`编辑`
按钮对R代码进行修改,保存后点击
`运行`
按钮即可。
## 示例
**1. 散点图**
请用diamonds画一个散点图,X轴是carat,Y轴是price,用color来区分颜色,并加上theme_bw()。
**2. 箱线图**
请用diamonds画箱线图,把price按cut分组,看看不同切工的价格分布。
**3. 直方图**
请用diamonds画carat的直方图,分面按clarity排布,bin宽度取0.1。
**4. 柱状图**
请用diamonds统计各color等级的数量,画一个柱状图,颜色按实际颜色填充。
**5. 密度图**
请用diamonds画出0.5~2克拉范围内,不同color的carat密度曲线,要求半透明重叠。
**6. 分组均值表**
请用diamonds按cut分组,计算每组price与carat的平均值、标准差,输出成表格。
**7. 价格对数-克拉线性拟合图**
请用diamonds画log(price)和carat的散点图,并加上回归直线,颜色按clarity区分,用theme_minimal()。
\ No newline at end of file
radiant.quickgen/inst/app/tools/help/quickgen_chart.md
0 → 100644
View file @
f261dcec
> 大模型生成描述性统计(图表)
## 使用方法
以下是
`大模型生成描述性统计`
的使用方法。
1.
`数据对象`
必须要有,且必须和数据集中的名字一致(大小写也一致)
2.
`图像类型`
必须要有,比如分布图、散点图等。可以要求模型返回多张图表,需向模型明确。
3.
`生成代码`
如果有误,或者想要修改,可以点击
`编辑`
按钮对R代码进行修改,保存后点击
`运行`
按钮即可。
## 示例
**1. 散点图**
请用该数据集画一个散点图,X 轴是 bmi(身体质量指数),Y 轴是 charges(年度医疗费用),用 smoker(吸烟状态)来区分颜色。
**2. 箱线图**
请用该数据集画箱线图,把 charges 按 smoker 分组,看看吸烟 / 不吸烟人群的医疗费用分布。
**3. 直方图**
请用该数据集画 age(年龄)的直方图,分面按 sex(性别)排布,bin 宽度取 2(年龄区间)。
**4. 柱状图**
请用该数据集统计各 region(居住区域)的样本数量,画一个柱状图,颜色按 region 实际类别填充。
**5. 密度图**
请用该数据集画出 bmi 在 18~35 范围内,不同 sex 的 bmi 密度曲线,要求半透明重叠展示。
**6. 分组均值表**
请用该数据集按 sex 分组,计算每组 age、bmi、charges 的平均值、标准差,输出成结构化表格。
**7. 费用 - 年龄线性拟合图**
请用该数据集画 charges 和 age 的散点图,并加上回归直线,颜色按 smoker 区分。
**8. 交叉频数表**
请用该数据集统计 sex 与 smoker 的交叉频数(即 “男性吸烟 / 不吸烟人数、女性吸烟 / 不吸烟人数”),输出二维汇总表格。
**9. 儿童数量分布柱状图**
请用该数据集统计 children(受抚养者数量)的不同取值对应的样本数,画一个柱状图展示各数量的分布。
**10. 区域 - 费用箱线图**
请用该数据集画箱线图,把 charges 按 region 分组,对比不同区域的医疗费用差异,并用不同颜色标注。
\ No newline at end of file
radiant.quickgen/inst/app/tools/help/quickgen_chat.md
View file @
f261dcec
> 大模型对话引导助手
### 1. 界面概述
本工具是
**“一键生成” 模块下的 R 语言科研辅助助手 **
,专为数据集的科研分析设计,可自动结合数据集字段信息,为你提供字段解读、分析方法建议、统计结果解读等科研支持。
### 2. 使用步骤
1.
**确认数据集**
:进入工具后,,字段信息会自动加载至智能体;
2.
发起对话
-
方式 1:点击预设问题按钮,快速发起提问;
-
方式 2:在底部输入框中自定义科研问题,点击右侧发送按钮提交;
3.
**获取回复**
:AI 会结合传入的字段信息,生成科研场景下的专业回复;
4.
**重置对话**
:若需切换分析主题,点击 “开启新对话” 清空历史即可。
### 3. 常见操作示例
#### 示例 1:字段解读(预设问题 1)
-
操作:点击 “这个数据集中的字段是什么意思?有什么科研分析用途?” 按钮
-
效果:AI 会解释
`insurance`
中
`age`
(年龄)、
`smoker`
(吸烟状态)、
`charges`
(医疗费用)等字段的含义,并说明各字段的科研分析场景(如
`smoker`
可用于分析吸烟对医疗费用的影响)。
#### 示例 2:分析方法建议(预设问题 2)
-
操作:点击 “基于当前数据集的字段信息,我该选择什么科研分析方法?” 按钮
-
效果:AI 会根据
`insurance`
的字段类型(如分类变量
`sex`
、数值变量
`charges`
),推荐适配的统计方法(如箱线图分析分组费用差异、线性回归分析年龄对费用的影响)。
#### 示例 3:统计结果解读(预设问题 3)
-
操作:点击 “我得到的科研结果(比如模型参数、统计指标)该怎么解读?” 按钮
-
效果:若你提供具体结果(如 “
`smoker`
对
`charges`
的回归系数是 20000”),AI 会解读该指标的科研意义(如 “吸烟人群的年度医疗费用平均比非吸烟人群高 20000 单位”)。
#### 示例 4:自定义科研问题
-
输入:“帮我说明用
`insurance`
数据集中
`bmi`
和
`charges`
做散点图的科研意义是什么?”
-
效果:AI 会结合两个字段的含义,解释散点图可用于观察身体质量指数与医疗费用的相关性,为后续回归分析提供可视化依据。
### 4. 注意事项
1.
字段信息会
**自动传递给 AI**
,无需手动输入数据集字段内容;
2.
“开启新对话” 会清空当前历史,若需保留对话记录,请勿点击该按钮。
\ No newline at end of file
radiant.quickgen/inst/app/tools/help/quickgen_metrics.md
0 → 100644
View file @
f261dcec
xxxxxx
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment