diff --git a/Dockerfile b/Dockerfile index 148b87c4782675b92a9ebf99e774bb447a95c9ea..2e3fac845305b098091e97375bd2a3fcee06dc90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,21 +6,26 @@ RUN apt-get update && apt-get install -y \ libpng-dev libtiff5-dev libjpeg-dev \ && rm -rf /var/lib/apt/lists/* - -RUN R -e "install.packages(c('shiny', 'shinydashboard', 'remotes'), repos='https://cran.rstudio.com/')" +RUN R -e "install.packages(c('shiny', 'shinydashboard', 'remotes','readxl'), repos='https://cran.rstudio.com/',dependencies=TRUE)" +RUN echo 'options(radiant.shinyFiles = FALSE)' >> /usr/local/lib/R/etc/Rprofile.site COPY . /srv/shiny-server/ COPY set_path.R /usr/local/lib/R/etc/Rprofile.site.d/00-radiant-path.R # 安装所有子模块 -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.data', type='source', upgrade='never')" -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.basics', type='source', upgrade='never')" -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.model', type='source', upgrade='never')" -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.multivariate', type='source', upgrade='never')" -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.design', type='source', upgrade='never')" -RUN R -e "remotes::install_local('/srv/shiny-server/radiant.quickgen', type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.data',dependencies=TRUE, type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.basics',dependencies=TRUE, type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.model',dependencies=TRUE, type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.multivariate',dependencies=TRUE, type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.design',dependencies=TRUE, type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant.quickgen',dependencies=TRUE, type='source', upgrade='never')" # 安装主 radiant 应用 -RUN R -e "remotes::install_local('/srv/shiny-server/radiant-master', type='source', upgrade='never')" +RUN R -e "remotes::install_local('/srv/shiny-server/radiant-master',dependencies=TRUE, type='source', upgrade='never')" WORKDIR /data -CMD ["R", "-e", "radiant::radiant(host='0.0.0.0', port=3838)"] \ No newline at end of file +CMD ["R", "-e", "radiant::radiant(host='0.0.0.0', port=3838)"] + +#docker images | grep radiant 查看镜像 +#sudo systemctl restart shinyproxy 重启proxy +#sudo vim /etc/shinyproxy/application.yml 修改配置文件 +#docker build -t radiant:latest . 构建镜像 \ No newline at end of file diff --git a/data/cancer.csv b/data/cancer.csv new file mode 100644 index 0000000000000000000000000000000000000000..4effa94c2e01d89df02881c117cf223919195c5b --- /dev/null +++ b/data/cancer.csv @@ -0,0 +1,930 @@ +ID,Hospital,Treatment,Age,Sex,Blood test,Obstruct,Perfor,Adhere,Differ,Extent,Effect,Occurrence,OS_status,OS_time,Objective Response +1,hospital_5,Lev,43,Male,3829,NA,No,No,Moderate,Serosa,Bad,5,1,1521,Yes +2,hospital_3,Lev,63,Male,3825,No,No,No,Moderate,Serosa,Good,1,0,3087,No +3,hospital_5,Obs,71,Female,3809,No,No,Yes,Moderate,Muscle,Bad,7,1,963,Yes +4,hospital_4,Lev,66,Female,3808,Yes,No,No,Moderate,Serosa,Bad,6,1,293,Yes +5,hospital_5,Obs,69,Male,3738,No,No,No,Moderate,Serosa,Bad,22,1,659,Yes +6,hospital_4,Lev,57,Female,3714,No,No,No,Moderate,Serosa,Bad,9,1,1767,Yes +7,hospital_2,Lev,77,Male,3692,No,No,No,Moderate,Serosa,Bad,5,1,420,Yes +8,hospital_2,Obs,54,Male,3685,No,No,No,Moderate,Serosa,Good,1,0,3192,No +9,hospital_2,Lev,46,Male,3673,No,No,Yes,Moderate,Serosa,Good,2,0,3173,Yes +10,hospital_2,Lev,68,Female,3587,No,No,No,Moderate,Serosa,Bad,1,0,3308,Yes +11,hospital_1,Lev,47,Female,3585,No,No,Yes,Moderate,Serosa,Bad,1,0,2908,No +12,hospital_1,Lev,52,Male,3578,No,No,No,Poor,Serosa,Bad,2,0,3309,Yes +13,hospital_3,Obs,64,Male,3530,No,No,No,Moderate,Serosa,Good,1,1,2085,Yes +14,hospital_4,Lev,68,Male,3524,Yes,No,No,Moderate,Serosa,Good,3,1,2910,Yes +15,hospital_1,Obs,46,Male,3519,Yes,No,No,Moderate,Serosa,Good,4,0,2754,Yes +16,hospital_1,Obs,68,Male,3517,No,No,No,Moderate,Serosa,Good,1,0,3214,Yes +17,hospital_4,Lev,62,Male,3500,Yes,No,Yes,Moderate,Serosa,Bad,6,1,406,Yes +18,hospital_5,Lev,79,Male,3485,Yes,No,No,Moderate,Serosa,Bad,1,1,522,Yes +19,hospital_1,Lev,34,Female,3469,Yes,No,No,Moderate,Muscle,Bad,1,1,887,No +20,hospital_1,Lev,50,Female,3469,No,No,Yes,Moderate,Serosa,Good,1,0,3329,No +21,hospital_2,Obs,64,Male,3458,NA,No,No,Moderate,Serosa,Good,1,1,2789,Yes +22,hospital_4,Lev,56,Male,3451,Yes,No,No,Moderate,Serosa,Bad,4,1,739,Yes +23,hospital_3,Lev,61,Female,3450,No,No,No,Moderate,Serosa,Bad,4,1,709,No +24,hospital_1,Lev,50,Female,3441,No,No,No,Moderate,Muscle,Good,1,0,2969,Yes +25,hospital_1,Lev,70,Female,3427,No,No,No,Moderate,Serosa,Good,4,0,2889,Yes +26,hospital_5,Obs,73,Male,3425,No,No,No,Moderate,Serosa,Bad,1,1,1772,No +27,hospital_5,Obs,70,Female,3418,No,No,Yes,Moderate,Serosa,Bad,13,1,384,Yes +28,hospital_5,Lev,68,Female,3416,No,No,No,Moderate,Serosa,Bad,1,1,968,Yes +29,hospital_4,Obs,56,Female,3415,Yes,No,No,Poor,Serosa,Bad,6,1,218,Yes +30,hospital_5,Lev,80,Male,3413,No,No,No,Poor,Serosa,Bad,1,1,133,No +31,hospital_2,Lev,64,Female,3410,No,No,No,Moderate,Submucosa,Good,1,0,3238,Yes +32,hospital_3,Lev,33,Female,3408,Yes,No,No,Moderate,Serosa,Good,3,0,3019,Yes +33,hospital_2,Obs,49,Female,3405,No,No,No,Moderate,Serosa,Bad,2,1,1745,No +34,hospital_5,Obs,47,Male,3401,No,No,No,Moderate,Serosa,Good,3,1,2527,Yes +35,hospital_4,Lev,56,Female,3399,No,No,No,Moderate,Serosa,Bad,1,1,1387,Yes +36,hospital_4,Lev,72,Female,3399,No,No,Yes,Poor,Serosa,Good,1,0,3024,Yes +37,hospital_5,Obs,79,Male,3389,No,No,No,Moderate,Serosa,Bad,19,1,570,Yes +38,hospital_2,Obs,64,Female,3383,No,No,No,Poor,Serosa,Good,1,0,2815,Yes +39,hospital_1,Lev,61,Male,3371,No,No,No,Poor,Serosa,Good,2,0,2901,Yes +40,hospital_2,Lev,58,Male,3369,No,No,No,Moderate,Serosa,Bad,7,1,553,No +41,hospital_3,Lev,75,Male,3362,No,No,No,Moderate,Serosa,Bad,2,1,905,Yes +42,hospital_3,Obs,39,Female,3349,Yes,No,No,Well,Serosa,Good,1,0,3030,Yes +43,hospital_3,Obs,71,Male,3342,Yes,No,No,Moderate,Muscle,Bad,3,1,685,Yes +44,hospital_2,Lev,58,Female,3340,Yes,No,No,Moderate,Serosa,Good,2,0,2740,Yes +45,hospital_3,Lev,40,Male,3335,No,No,No,Well,Serosa,Good,1,0,2899,No +46,hospital_1,Obs,63,Female,3328,No,Yes,No,Moderate,Serosa,Good,2,0,2598,No +47,hospital_1,Lev,59,Female,3326,No,No,No,Poor,Submucosa,Good,1,0,2840,Yes +48,hospital_1,Lev,59,Female,3321,Yes,No,No,Well,Serosa,Good,2,0,2802,Yes +49,hospital_4,Lev,59,Male,3320,No,No,No,Moderate,Serosa,Good,6,0,2781,Yes +50,hospital_3,Lev,60,Male,3315,No,No,No,Poor,Serosa,Bad,5,1,833,Yes +51,hospital_4,Obs,68,Female,3315,No,No,No,Moderate,Serosa,Bad,2,1,1290,No +52,hospital_3,Lev,70,Female,3302,No,No,No,Moderate,Serosa,Bad,3,1,1620,Yes +53,hospital_1,Obs,76,Male,3300,No,No,No,Moderate,Serosa,Good,2,0,2765,Yes +54,hospital_4,Lev,45,Female,3294,No,No,No,Moderate,Serosa,Bad,3,0,2708,Yes +55,hospital_3,Lev,61,Male,3289,No,No,No,Moderate,Muscle,Bad,2,0,2737,Yes +56,hospital_4,Obs,76,Male,3289,No,No,No,Well,Serosa,Bad,3,1,1178,No +57,hospital_3,Lev,53,Male,3281,No,No,No,Moderate,Serosa,Good,2,0,2765,Yes +58,hospital_1,Lev,63,Female,3279,No,No,No,Moderate,Serosa,Good,5,0,2883,Yes +59,hospital_2,Obs,65,Female,3275,No,No,No,Poor,Serosa,Good,6,0,2679,Yes +60,hospital_3,Obs,57,Female,3272,Yes,No,No,Poor,Serosa,Good,4,0,2925,No +61,hospital_4,Lev,80,Male,3265,No,Yes,No,Moderate,Serosa,Bad,4,1,472,Yes +62,hospital_1,Lev,58,Male,3265,No,No,No,Well,Muscle,Good,1,0,2772,Yes +63,hospital_5,Obs,53,Female,3265,No,No,No,Poor,Serosa,Bad,15,1,474,No +64,hospital_3,Lev,53,Female,3264,Yes,No,No,NA,Serosa,Good,1,0,2739,Yes +65,hospital_4,Obs,71,Female,3261,No,No,No,Well,Serosa,Bad,1,1,365,Yes +66,hospital_1,Lev,66,Female,3261,No,No,No,Moderate,Serosa,Good,2,0,2653,Yes +67,hospital_4,Lev,49,Male,3260,No,No,No,Poor,Serosa,Good,6,0,2726,No +68,hospital_5,Obs,60,Male,3254,No,No,No,Moderate,Serosa,Bad,10,1,774,Yes +69,hospital_3,Obs,70,Female,3254,No,No,No,Moderate,Submucosa,Good,3,0,3078,Yes +70,hospital_4,Obs,40,Female,3247,No,No,No,Moderate,Serosa,Good,2,1,2133,No +71,hospital_2,Lev,55,Female,3247,No,No,No,Moderate,Serosa,Good,1,1,2127,No +72,hospital_4,Lev,56,Female,3243,No,No,No,Moderate,Serosa,Bad,15,1,400,Yes +73,hospital_5,Lev,54,Male,3240,No,No,No,Moderate,Serosa,Good,9,0,3185,Yes +74,hospital_5,Obs,49,Female,3239,Yes,No,No,Poor,Serosa,Bad,5,1,1237,Yes +75,hospital_5,Lev,71,Female,3237,No,No,No,Moderate,Serosa,Bad,7,1,1219,No +76,hospital_4,Obs,67,Female,3232,No,No,No,Moderate,Serosa,Good,4,0,3017,Yes +77,hospital_2,Lev,68,Female,3231,No,No,No,Moderate,Serosa,Bad,5,1,806,Yes +78,hospital_1,Lev,63,Male,3230,No,No,No,Moderate,Serosa,Good,2,0,2985,Yes +79,hospital_2,Lev,50,Male,3230,Yes,No,Yes,Moderate,Serosa,Good,1,0,2969,Yes +80,hospital_5,Lev,45,Female,3226,No,No,No,Moderate,Muscle,Good,7,1,1995,Yes +81,hospital_3,Lev,66,Male,3226,No,No,No,Moderate,Muscle,Good,1,0,2958,Yes +82,hospital_4,Obs,46,Female,3225,No,No,No,Poor,Serosa,Bad,1,1,1133,No +83,hospital_5,Lev,70,Male,3224,No,No,No,NA,Muscle,Bad,3,1,1548,Yes +84,hospital_1,Lev,63,Male,3223,Yes,No,No,Moderate,Muscle,Good,2,0,3085,Yes +85,hospital_4,Lev,45,Male,3223,No,No,No,Poor,Serosa,Bad,8,1,736,No +86,hospital_1,Lev,49,Female,3220,No,No,No,Moderate,Serosa,Good,1,0,2789,Yes +87,hospital_2,Lev,62,Female,3218,No,No,No,Moderate,Muscle,Good,2,0,3325,Yes +88,hospital_4,Obs,59,Male,3216,No,No,No,Moderate,Serosa,Bad,4,1,381,No +89,hospital_1,Lev,80,Female,3213,NA,No,No,Well,Serosa,Good,4,0,2724,Yes +90,hospital_3,Lev,73,Male,3211,Yes,No,No,NA,Serosa,Bad,4,1,997,Yes +91,hospital_5,Obs,46,Male,3209,No,No,No,Moderate,Serosa,Bad,11,1,413,Yes +92,hospital_2,Lev,64,Male,3208,No,No,No,Moderate,Serosa,Bad,4,1,708,Yes +93,hospital_3,Lev,45,Male,3206,No,No,No,Moderate,Serosa,Good,9,0,2765,No +94,hospital_3,Lev,26,Female,3203,No,No,Yes,Moderate,Adjacent structures,Bad,NA,0,2869,No +95,hospital_1,Lev,66,Male,3199,NA,No,No,Moderate,Serosa,Bad,1,0,2918,Yes +96,hospital_3,Lev,67,Male,3197,No,No,Yes,Moderate,Adjacent structures,Bad,2,1,2458,Yes +97,hospital_5,Obs,65,Female,3195,No,No,No,Moderate,Adjacent structures,Bad,20,1,459,Yes +98,hospital_2,Lev,74,Male,3191,No,No,Yes,Moderate,Serosa,Good,1,1,2318,Yes +99,hospital_2,Lev,71,Male,3190,No,No,Yes,Moderate,Adjacent structures,Bad,NA,1,569,Yes +100,hospital_5,Obs,58,Female,3188,No,No,Yes,Moderate,Muscle,Good,8,1,2077,Yes +101,hospital_5,Obs,59,Male,3183,No,No,No,Moderate,Serosa,Bad,6,1,1216,Yes +102,hospital_5,Lev,61,Male,3182,NA,No,No,Poor,Serosa,Bad,5,1,171,Yes +103,hospital_4,Lev,49,Male,3179,No,No,No,Moderate,Serosa,Bad,2,1,712,Yes +104,hospital_5,Lev,50,Female,3179,No,No,No,Moderate,Serosa,Bad,6,1,614,No +105,hospital_1,Obs,75,Female,3178,No,No,No,Moderate,Serosa,Good,1,0,2849,No +106,hospital_3,Obs,68,Male,3176,No,No,No,Poor,Serosa,Bad,3,1,1530,Yes +107,hospital_4,Lev,60,Female,3174,No,No,Yes,Moderate,Serosa,Bad,10,1,402,Yes +108,hospital_5,Lev,65,Female,3172,No,No,Yes,Moderate,Serosa,Bad,2,1,1511,Yes +109,hospital_4,Lev,74,Female,3168,No,No,No,Moderate,Serosa,Good,5,0,2828,No +110,hospital_2,Lev,52,Female,3163,No,No,No,Poor,Serosa,Bad,3,1,23,Yes +111,hospital_1,Lev,64,Male,3156,No,No,Yes,Moderate,Serosa,Good,6,0,2941,Yes +112,hospital_3,Lev,47,Male,3156,No,No,Yes,Moderate,Serosa,Bad,1,1,755,Yes +113,hospital_1,Obs,45,Female,3153,No,No,No,Moderate,Submucosa,Good,1,0,2815,Yes +114,hospital_5,Obs,61,Male,3151,Yes,No,Yes,Poor,Serosa,Bad,5,1,761,Yes +115,hospital_2,Lev,53,Male,3148,No,No,No,Poor,Serosa,Good,2,1,1839,No +116,hospital_4,Obs,60,Male,3131,Yes,No,No,Moderate,Serosa,Good,5,1,2351,Yes +117,hospital_1,Lev,60,Female,3130,No,No,No,Moderate,Serosa,Good,1,0,2760,Yes +118,hospital_1,Lev,51,Female,3128,No,No,No,Moderate,Serosa,Good,5,0,2951,No +119,hospital_1,Lev,60,Female,3128,No,No,Yes,Moderate,Serosa,Good,1,0,2820,No +120,hospital_5,Obs,64,Female,3121,No,No,No,Moderate,Serosa,Bad,1,1,1327,Yes +121,hospital_2,Lev,52,Female,3118,No,No,No,Moderate,Serosa,Good,1,0,2678,Yes +122,hospital_3,Lev,65,Female,3118,No,No,No,Poor,Serosa,Bad,2,1,226,No +123,hospital_3,Lev,70,Female,3113,No,No,No,Moderate,Serosa,Good,1,0,2913,Yes +124,hospital_2,Obs,55,Male,3100,No,No,No,Moderate,Serosa,Good,2,0,2862,Yes +125,hospital_5,Lev,71,Male,3098,No,No,No,Poor,Serosa,Bad,5,1,454,Yes +126,hospital_3,Obs,30,Male,3093,No,No,No,Moderate,Muscle,Good,1,0,2743,Yes +127,hospital_2,Obs,40,Female,3092,No,No,No,Moderate,Serosa,Bad,3,1,1679,No +128,hospital_5,Obs,31,Male,3092,Yes,No,No,Poor,Serosa,Bad,11,1,924,No +129,hospital_3,Obs,53,Male,3090,No,No,No,Moderate,Muscle,Bad,1,1,721,No +130,hospital_4,Obs,67,Male,3088,No,No,No,Moderate,Serosa,Bad,1,1,709,No +131,hospital_3,Lev,58,Female,3080,No,No,No,Moderate,Serosa,Bad,1,1,961,No +132,hospital_4,Lev,79,Female,3077,Yes,No,No,Poor,Serosa,Bad,2,1,326,Yes +133,hospital_4,Lev,55,Female,3077,No,No,No,Poor,Muscle,Good,1,0,2703,Yes +134,hospital_3,Obs,63,Female,3074,No,No,Yes,Moderate,Serosa,Bad,2,1,289,Yes +135,hospital_3,Lev,55,Male,3072,Yes,No,No,Moderate,Serosa,Good,2,0,2905,No +136,hospital_5,Lev,42,Male,3068,Yes,No,No,Moderate,Serosa,Bad,5,1,206,No +137,hospital_2,Obs,56,Male,3065,No,No,No,Moderate,Serosa,Good,1,0,2618,Yes +138,hospital_3,Lev,64,Female,3062,No,No,No,Moderate,Serosa,Bad,8,1,283,No +139,hospital_2,Lev,55,Male,3058,Yes,No,No,Moderate,Serosa,Good,2,1,2718,Yes +140,hospital_1,Obs,25,Female,3058,Yes,No,No,Moderate,Serosa,Good,7,0,2826,Yes +141,hospital_4,Lev,59,Male,3055,No,No,No,Moderate,Serosa,Good,1,0,2916,Yes +142,hospital_5,Lev,28,Male,3052,No,No,No,Poor,Serosa,Bad,9,1,499,No +143,hospital_2,Lev,49,Female,3051,No,No,No,Well,Serosa,Good,NA,0,2950,Yes +144,hospital_4,Obs,52,Female,3048,No,No,No,Moderate,Submucosa,Good,1,0,2899,Yes +145,hospital_2,Obs,64,Female,3047,No,No,No,Poor,Serosa,Bad,5,1,673,Yes +146,hospital_1,Obs,33,Female,3045,Yes,No,Yes,Well,Serosa,Good,1,0,3000,No +147,hospital_4,Obs,76,Male,3044,No,No,No,Moderate,Serosa,Good,1,1,2284,No +148,hospital_5,Lev,38,Male,3042,No,No,No,Well,Serosa,Bad,2,1,362,Yes +149,hospital_2,Lev,53,Female,3041,Yes,Yes,No,Moderate,Serosa,Good,1,1,2152,Yes +150,hospital_1,Obs,72,Female,3040,Yes,No,No,Moderate,Serosa,Good,2,0,2562,Yes +151,hospital_1,Lev,46,Male,3038,No,No,No,Moderate,Serosa,Good,1,0,2730,Yes +152,hospital_5,Lev,69,Female,3032,No,No,No,Moderate,Serosa,Bad,13,1,802,Yes +153,hospital_5,Obs,43,Male,3030,Yes,No,No,Poor,Serosa,Bad,0,1,1166,Yes +154,hospital_4,Lev,72,Male,3030,Yes,No,Yes,Moderate,Serosa,Bad,2,1,1193,No +155,hospital_4,Lev,73,Male,3028,Yes,No,No,Moderate,Serosa,Bad,2,1,45,Yes +156,hospital_1,Obs,68,Male,3027,No,No,No,Moderate,Serosa,Good,3,0,2577,Yes +157,hospital_5,Obs,52,Female,3027,No,Yes,No,Well,Serosa,Bad,6,1,1136,No +158,hospital_2,Lev,73,Female,3027,Yes,No,No,Moderate,Serosa,Good,2,0,2497,Yes +159,hospital_3,Lev,66,Male,3025,Yes,No,No,Moderate,Serosa,Good,1,0,2648,Yes +160,hospital_1,Obs,75,Female,3020,No,No,No,Poor,Serosa,Good,2,0,2458,No +161,hospital_5,Lev,43,Male,3020,Yes,No,No,NA,Serosa,Bad,6,1,1135,Yes +162,hospital_5,Lev,57,Female,3017,No,No,No,Moderate,Serosa,Bad,1,1,580,Yes +163,hospital_4,Obs,74,Male,3017,Yes,No,No,Moderate,Serosa,Bad,6,1,485,Yes +164,hospital_1,Lev,67,Female,3017,No,No,No,Moderate,Serosa,Good,1,0,2656,Yes +165,hospital_4,Lev,66,Female,3013,No,No,Yes,Moderate,Serosa,Bad,2,1,806,Yes +166,hospital_4,Obs,57,Male,3013,Yes,No,No,Moderate,Serosa,Good,3,0,2435,Yes +167,hospital_2,Lev,81,Female,3009,No,No,No,Moderate,Serosa,Bad,3,1,1439,Yes +168,hospital_3,Obs,50,Male,3007,No,No,No,Poor,Serosa,Bad,4,1,717,Yes +169,hospital_4,Lev,62,Male,3006,Yes,Yes,No,Moderate,Serosa,Good,2,0,2568,Yes +170,hospital_1,Lev,48,Female,3006,No,No,No,Well,Serosa,Good,4,0,2631,Yes +171,hospital_3,Lev,45,Male,3005,No,No,No,Moderate,Muscle,NA,2,0,1474,No +172,hospital_4,Lev,46,Male,3003,No,No,Yes,Moderate,Serosa,Good,2,1,2593,Yes +173,hospital_3,Lev,72,Female,3001,No,No,No,Moderate,Serosa,Bad,2,1,1550,Yes +174,hospital_2,Obs,55,Female,2997,No,No,No,Moderate,Serosa,Bad,4,1,670,Yes +175,hospital_4,Lev,67,Male,2997,Yes,No,No,Moderate,Serosa,Bad,1,1,430,Yes +176,hospital_3,Lev,41,Female,2996,No,No,No,Moderate,Serosa,Good,2,0,2821,Yes +177,hospital_4,Lev,56,Male,2995,No,No,No,Moderate,Submucosa,Good,2,0,2672,Yes +178,hospital_2,Lev,50,Male,2990,No,No,No,Moderate,Submucosa,Good,4,0,2699,No +179,hospital_1,Lev,65,Female,2988,No,No,No,Well,Muscle,Good,1,0,2927,Yes +180,hospital_2,Lev,74,Male,2988,No,No,Yes,Moderate,Serosa,Bad,1,1,993,No +181,hospital_4,Obs,74,Female,2987,No,No,No,Moderate,Serosa,Good,2,0,2580,No +182,hospital_4,Obs,58,Female,2987,No,No,No,Moderate,Serosa,Good,4,0,2621,Yes +183,hospital_1,Lev,56,Female,2986,No,No,No,Poor,Serosa,Good,4,0,2779,Yes +184,hospital_2,Obs,75,Female,2985,No,No,No,Moderate,Muscle,Good,1,0,2794,No +185,hospital_1,Lev,67,Male,2984,No,No,No,Moderate,Serosa,Good,4,0,2656,Yes +186,hospital_2,Lev,58,Female,2982,No,No,No,Well,Serosa,Good,6,0,2513,No +187,hospital_1,Lev,58,Female,2981,No,No,No,Moderate,Serosa,Good,2,0,2488,No +188,hospital_5,Lev,41,Male,2974,No,No,No,Poor,Serosa,Bad,33,1,1112,Yes +189,hospital_1,Lev,72,Male,2972,No,No,No,Moderate,Serosa,Good,NA,0,2618,No +190,hospital_4,Lev,48,Male,2972,No,No,Yes,NA,Serosa,Bad,2,1,795,Yes +191,hospital_5,Lev,69,Female,2972,No,No,No,Moderate,Serosa,Bad,1,1,363,Yes +192,hospital_5,Obs,57,Male,2967,Yes,No,Yes,Moderate,Serosa,Bad,1,1,949,No +193,hospital_1,Lev,45,Female,2961,Yes,No,Yes,Moderate,Serosa,Bad,1,1,127,Yes +194,hospital_2,Lev,76,Female,2960,No,No,No,Moderate,Serosa,Good,4,0,2871,No +195,hospital_3,Obs,59,Male,2958,No,No,Yes,Moderate,Serosa,Good,2,0,2558,No +196,hospital_2,Obs,66,Female,2958,No,No,No,Moderate,Serosa,Good,1,1,2083,No +197,hospital_2,Obs,65,Female,2956,No,No,No,Poor,Muscle,Good,1,0,2747,Yes +198,hospital_4,Lev,69,Male,2950,No,No,No,Well,Serosa,Bad,1,1,1105,Yes +199,hospital_4,Lev,32,Female,2949,No,No,No,Poor,Serosa,Bad,NA,1,490,No +200,hospital_2,Obs,56,Female,2949,No,No,No,NA,Muscle,Good,1,0,2507,Yes +201,hospital_2,Lev,71,Male,2947,No,No,No,Well,Serosa,Bad,1,1,961,Yes +202,hospital_5,Lev,75,Male,2945,No,No,No,NA,Serosa,Good,8,1,1879,Yes +203,hospital_1,Lev,58,Male,2944,No,No,No,Poor,Serosa,Good,7,0,2592,Yes +204,hospital_4,Obs,40,Female,2942,No,No,No,Moderate,Serosa,Good,4,1,2552,Yes +205,hospital_4,Lev,39,Female,2941,No,No,No,Well,Submucosa,Good,2,0,2474,No +206,hospital_1,Lev,42,Female,2939,No,No,No,Moderate,Serosa,Good,4,0,2349,No +207,hospital_3,Lev,53,Female,2935,No,No,No,Well,Submucosa,Good,4,0,2835,Yes +208,hospital_2,Obs,43,Male,2929,No,No,No,Moderate,Serosa,Good,2,0,2761,Yes +209,hospital_3,Obs,51,Female,2923,No,No,No,Moderate,Serosa,Bad,4,1,411,Yes +210,hospital_1,Lev,77,Male,2923,No,No,No,Well,Serosa,Good,2,0,2720,Yes +211,hospital_2,Lev,67,Male,2922,Yes,No,No,Moderate,Serosa,Good,1,0,2495,Yes +212,hospital_3,Obs,41,Male,2916,No,No,No,Moderate,Serosa,Bad,7,1,462,No +213,hospital_1,Lev,63,Male,2914,Yes,Yes,Yes,Poor,Adjacent structures,Good,2,0,2497,Yes +214,hospital_1,Lev,63,Male,2913,No,No,Yes,Moderate,Muscle,Good,3,0,2343,Yes +215,hospital_4,Lev,63,Female,2910,No,No,No,Moderate,Serosa,Good,6,0,2630,Yes +216,hospital_4,Lev,58,Female,2908,Yes,No,No,Moderate,Serosa,Good,8,0,2461,Yes +217,hospital_3,Lev,67,Female,2896,No,No,No,Moderate,Adjacent structures,Good,4,0,2747,No +218,hospital_5,Lev,55,Male,2894,Yes,No,No,Moderate,Serosa,Good,7,1,2482,Yes +219,hospital_2,Lev,63,Male,2893,Yes,No,No,Poor,Serosa,Bad,5,1,580,Yes +220,hospital_4,Lev,77,Male,2893,No,No,Yes,Moderate,Serosa,Bad,1,1,1215,Yes +221,hospital_2,Lev,43,Male,2891,Yes,Yes,Yes,Poor,Serosa,Good,4,0,2525,Yes +222,hospital_1,Lev,78,Female,2891,No,No,No,Moderate,Muscle,Good,2,0,2842,Yes +223,hospital_5,Obs,51,Female,2887,No,No,Yes,Moderate,Serosa,Bad,5,1,1272,Yes +224,hospital_2,Obs,67,Male,2886,Yes,No,No,Moderate,Serosa,Bad,1,1,438,No +225,hospital_2,Lev,66,Male,2886,No,No,No,Moderate,Serosa,Good,1,0,2423,Yes +226,hospital_4,Obs,64,Female,2885,No,No,Yes,Moderate,Adjacent structures,Bad,1,1,599,Yes +227,hospital_2,Obs,75,Female,2884,Yes,No,Yes,Moderate,Serosa,Good,1,0,2706,Yes +228,hospital_5,Lev,53,Male,2881,No,No,No,Moderate,Serosa,Good,1,1,2683,Yes +229,hospital_3,Lev,48,Male,2880,Yes,Yes,No,Moderate,Serosa,Good,2,0,2723,Yes +230,hospital_3,Obs,59,Female,2878,No,No,Yes,Moderate,Adjacent structures,Bad,1,1,1230,No +231,hospital_3,Obs,60,Female,2875,No,No,No,Moderate,Serosa,Good,1,0,2731,Yes +232,hospital_2,Obs,42,Male,2865,No,No,No,Moderate,Serosa,Good,2,0,2313,Yes +233,hospital_3,Lev,60,Male,2864,No,No,No,Moderate,Muscle,Good,1,0,2484,No +234,hospital_1,Lev,58,Male,2862,NA,No,No,Well,Serosa,Good,1,0,2754,Yes +235,hospital_3,Lev,59,Male,2860,NA,No,No,Moderate,Muscle,Good,2,1,2725,Yes +236,hospital_5,Obs,70,Female,2856,No,No,No,Moderate,Serosa,Bad,2,1,1295,Yes +237,hospital_1,Lev,75,Female,2855,No,No,No,Moderate,Serosa,Good,3,0,2506,Yes +238,hospital_3,Lev,73,Female,2853,No,No,No,Moderate,Serosa,Good,3,0,2713,Yes +239,hospital_4,Obs,76,Male,2852,No,No,No,Moderate,Serosa,Good,1,0,2695,Yes +240,hospital_5,Lev,68,Female,2852,No,No,No,Moderate,Serosa,Bad,3,1,1276,Yes +241,hospital_3,Lev,61,Male,2851,No,No,No,Moderate,Adjacent structures,Good,2,0,2600,No +242,hospital_2,Lev,76,Male,2850,NA,No,No,Moderate,Muscle,Good,1,0,2352,No +243,hospital_1,Lev,56,Female,2850,No,Yes,Yes,Moderate,Serosa,Good,3,0,2775,Yes +244,hospital_2,Lev,55,Female,2849,Yes,No,No,NA,Serosa,Good,2,0,2442,Yes +245,hospital_3,Obs,60,Female,2847,Yes,No,Yes,Poor,Serosa,Bad,4,1,437,No +246,hospital_3,Lev,72,Male,2845,No,No,No,Moderate,Serosa,Bad,9,1,1709,Yes +247,hospital_3,Lev,74,Female,2843,Yes,No,No,Moderate,Serosa,Bad,11,1,1607,Yes +248,hospital_3,Lev,62,Female,2839,No,No,No,Moderate,Serosa,Bad,3,1,1637,No +249,hospital_4,Lev,76,Female,2832,No,No,No,Well,Serosa,Bad,1,1,1117,Yes +250,hospital_2,Lev,72,Male,2832,No,No,No,Moderate,Serosa,Good,2,0,2732,Yes +251,hospital_4,Lev,57,Male,2831,No,No,No,Poor,Serosa,Bad,2,1,222,Yes +252,hospital_3,Obs,39,Female,2831,No,No,No,Moderate,Adjacent structures,Good,1,0,2688,No +253,hospital_3,Lev,61,Male,2831,No,No,No,Moderate,Serosa,Good,1,0,2520,Yes +254,hospital_5,Obs,62,Female,2830,No,No,No,Poor,Serosa,Bad,5,1,595,Yes +255,hospital_4,Lev,70,Male,2826,No,No,No,Moderate,Serosa,Bad,2,1,343,No +256,hospital_4,Obs,70,Female,2825,No,No,No,Moderate,Serosa,Bad,5,1,874,Yes +257,hospital_5,Lev,57,Female,2824,Yes,No,No,Moderate,Serosa,Bad,8,1,232,Yes +258,hospital_3,Lev,65,Male,2823,No,No,No,Moderate,Muscle,Good,3,0,2558,Yes +259,hospital_3,Lev,65,Female,2821,No,No,No,Moderate,Serosa,Good,1,0,2711,Yes +260,hospital_5,Obs,71,Female,2818,No,No,No,Moderate,Serosa,Bad,15,1,113,Yes +261,hospital_5,Lev,70,Female,2816,Yes,No,No,Moderate,Serosa,Bad,3,1,643,Yes +262,hospital_2,Obs,36,Female,2813,No,No,No,Moderate,Serosa,Good,1,0,2413,No +263,hospital_1,Lev,48,Male,2813,No,No,No,Moderate,Submucosa,Good,2,0,2509,Yes +264,hospital_1,Lev,53,Male,2812,No,No,No,Well,Serosa,Good,1,0,2356,Yes +265,hospital_5,Lev,54,Male,2810,No,No,No,Moderate,Serosa,Bad,3,1,1279,Yes +266,hospital_3,Lev,58,Male,2809,No,No,No,Well,Serosa,Bad,3,1,938,Yes +267,hospital_3,Obs,67,Male,2804,No,No,No,Moderate,Serosa,Good,3,0,2761,No +268,hospital_3,Lev,59,Male,2803,Yes,No,No,Moderate,Serosa,Good,2,0,2386,No +269,hospital_2,Obs,67,Female,2800,No,No,Yes,Moderate,Serosa,Bad,4,1,433,Yes +270,hospital_2,Lev,60,Female,2799,Yes,No,No,Poor,Serosa,Good,1,0,2445,Yes +271,hospital_1,Lev,70,Female,2799,No,No,No,Moderate,Muscle,Good,1,0,2280,Yes +272,hospital_3,Obs,76,Male,3194,No,No,No,Well,Serosa,Bad,3,1,311,Yes +273,hospital_4,Lev,60,Male,3192,Yes,No,No,Well,Serosa,Bad,1,1,977,No +274,hospital_5,Obs,67,Female,3190,Yes,No,No,Well,Serosa,Bad,12,1,833,Yes +275,hospital_4,Lev,53,Male,3189,No,No,No,Moderate,Serosa,Bad,3,1,582,Yes +276,hospital_4,Lev,76,Female,3187,No,No,No,Well,Serosa,Good,1,0,2541,Yes +277,hospital_4,Obs,74,Male,3184,No,No,No,Moderate,Serosa,Bad,2,1,238,Yes +278,hospital_2,Obs,56,Female,3184,Yes,No,No,Moderate,Adjacent structures,Good,6,1,2257,No +279,hospital_4,Lev,65,Female,3180,No,No,No,Moderate,Muscle,Good,1,0,2501,Yes +280,hospital_2,Lev,63,Male,3179,No,No,No,Moderate,Serosa,Bad,2,1,1798,Yes +281,hospital_2,Obs,56,Male,3178,No,No,No,Moderate,Serosa,Bad,2,1,883,Yes +282,hospital_3,Lev,70,Female,3178,No,No,Yes,Poor,Serosa,Good,4,0,2548,No +283,hospital_3,Lev,48,Female,3177,No,No,No,Moderate,Serosa,Good,9,0,2527,Yes +284,hospital_2,Lev,45,Male,3174,Yes,No,No,Moderate,Serosa,Good,2,0,2263,Yes +285,hospital_4,Lev,68,Female,3170,No,No,No,Moderate,Serosa,Bad,8,1,706,No +286,hospital_1,Lev,57,Female,3169,No,No,No,Moderate,Muscle,Good,1,0,2588,Yes +287,hospital_5,Lev,70,Male,3167,No,No,No,Moderate,Muscle,Good,1,1,2542,Yes +288,hospital_1,Lev,39,Male,3165,No,No,No,Moderate,Serosa,NA,1,0,1279,Yes +289,hospital_1,Obs,46,Male,3164,No,No,Yes,Poor,Adjacent structures,Bad,1,1,1304,No +290,hospital_2,Obs,77,Female,3163,Yes,No,No,Moderate,Serosa,Good,4,0,2324,Yes +291,hospital_1,Lev,59,Male,3163,NA,No,No,Well,Serosa,Good,1,0,2488,Yes +292,hospital_4,Lev,58,Female,3161,No,No,No,Moderate,Serosa,Good,1,0,2628,No +293,hospital_2,Obs,56,Male,3157,No,No,No,Moderate,Serosa,Good,8,0,2800,No +294,hospital_1,Lev,68,Male,3157,No,No,No,NA,Serosa,Good,2,0,2456,Yes +295,hospital_2,Obs,57,Female,3155,No,Yes,Yes,Moderate,Serosa,Good,1,0,2503,Yes +296,hospital_4,Lev,44,Female,3154,No,No,No,Moderate,Serosa,Bad,3,1,1446,Yes +297,hospital_5,Lev,56,Male,3152,No,No,Yes,Moderate,Serosa,Bad,3,1,641,No +298,hospital_5,Obs,67,Male,3150,No,No,No,Moderate,Serosa,Bad,4,1,1788,Yes +299,hospital_3,Lev,62,Male,3150,No,No,No,Moderate,Muscle,Good,6,0,2304,Yes +300,hospital_3,Lev,68,Female,3145,No,No,No,Moderate,Serosa,Bad,7,1,944,Yes +301,hospital_3,Lev,61,Male,3144,No,No,No,Moderate,Muscle,Good,2,0,2679,Yes +302,hospital_3,Lev,44,Female,3142,Yes,No,No,Moderate,Serosa,Bad,5,1,559,Yes +303,hospital_2,Lev,52,Female,3140,No,No,No,Moderate,Serosa,Good,7,0,2663,Yes +304,hospital_3,Lev,51,Male,3137,Yes,No,No,Poor,Serosa,Bad,1,1,647,No +305,hospital_1,Obs,59,Female,3135,No,No,No,Moderate,Serosa,Good,9,0,2697,Yes +306,hospital_3,Lev,61,Male,3134,No,No,No,Poor,Serosa,Good,1,0,2538,Yes +307,hospital_2,Obs,57,Female,3132,No,No,No,Poor,Serosa,Good,2,0,2219,No +308,hospital_3,Lev,65,Male,3131,No,No,No,Moderate,Serosa,Good,1,0,2487,Yes +309,hospital_4,Lev,73,Female,3131,Yes,No,No,Moderate,Serosa,Good,1,0,2709,Yes +310,hospital_5,Obs,69,Female,3129,No,No,No,Poor,Serosa,Bad,6,1,840,No +311,hospital_1,Lev,63,Male,3129,No,No,No,Moderate,Serosa,Good,1,0,2267,Yes +312,hospital_3,Lev,75,Male,3127,No,No,No,Moderate,Muscle,Good,2,0,2444,Yes +313,hospital_2,Lev,64,Female,3127,No,No,No,Well,Serosa,Good,5,0,2393,Yes +314,hospital_1,Obs,56,Female,3122,No,No,No,Well,Submucosa,Good,1,0,2237,Yes +315,hospital_2,Lev,69,Male,3121,No,No,No,Moderate,Serosa,Good,2,0,2915,No +316,hospital_2,Lev,64,Female,3119,No,No,No,Moderate,Serosa,Good,2,0,2467,No +317,hospital_2,Lev,74,Female,3119,Yes,No,No,Moderate,Serosa,Bad,2,1,1092,Yes +318,hospital_3,Lev,72,Male,3113,No,No,No,Moderate,Muscle,Good,4,0,2726,Yes +319,hospital_4,Lev,58,Male,3113,Yes,No,No,Moderate,Serosa,Good,9,0,2764,Yes +320,hospital_3,Lev,74,Female,3112,No,No,Yes,Poor,Adjacent structures,Good,15,0,2592,Yes +321,hospital_1,Obs,61,Female,3112,No,No,No,Well,Muscle,Good,2,0,2730,Yes +322,hospital_1,Obs,74,Female,3110,NA,No,No,Moderate,Muscle,Good,1,1,2287,Yes +323,hospital_3,Lev,64,Male,3110,No,No,No,Moderate,Serosa,Good,5,0,2117,Yes +324,hospital_5,Lev,71,Female,3109,No,No,No,Moderate,Serosa,Bad,20,1,1668,Yes +325,hospital_1,Obs,66,Female,3107,No,No,Yes,NA,Adjacent structures,Bad,1,1,528,Yes +326,hospital_1,Obs,53,Female,3104,Yes,No,No,Well,Serosa,Good,2,0,2651,No +327,hospital_1,Lev,76,Female,3104,Yes,No,No,Moderate,Serosa,Good,1,0,2676,No +328,hospital_5,Lev,75,Female,3103,Yes,No,Yes,Moderate,Muscle,Good,3,1,1885,Yes +329,hospital_4,Lev,64,Male,3102,No,No,No,NA,Serosa,Good,3,0,2350,Yes +330,hospital_5,Lev,65,Male,3100,No,No,No,Moderate,Serosa,Bad,8,1,475,Yes +331,hospital_3,Obs,57,Female,3100,No,No,No,Moderate,Serosa,Bad,5,1,1246,No +332,hospital_3,Lev,65,Male,3098,No,No,Yes,Poor,Serosa,Good,1,0,2204,Yes +333,hospital_1,Obs,53,Male,3098,No,No,No,Moderate,Adjacent structures,Good,2,0,2716,Yes +334,hospital_2,Lev,74,Male,3097,No,No,No,Moderate,Serosa,Bad,4,1,797,Yes +335,hospital_2,Lev,74,Male,3095,No,No,No,Moderate,Serosa,Good,1,0,2527,Yes +336,hospital_4,Lev,74,Female,3094,No,No,Yes,Poor,Serosa,Good,1,1,2021,Yes +337,hospital_3,Lev,48,Female,3092,No,No,No,Moderate,Serosa,Bad,6,1,498,No +338,hospital_3,Lev,58,Male,3091,No,No,No,Poor,Serosa,Bad,NA,1,885,Yes +339,hospital_4,Lev,74,Female,3091,No,No,No,Moderate,Serosa,Bad,3,1,802,Yes +340,hospital_1,Lev,71,Female,3091,No,No,No,Moderate,Serosa,Good,1,0,2674,No +341,hospital_2,Obs,54,Female,3091,No,No,No,Moderate,Serosa,Bad,2,1,743,No +342,hospital_4,Lev,80,Male,3090,No,No,No,Moderate,Muscle,Good,4,0,2517,Yes +343,hospital_5,Lev,70,Male,3090,No,No,Yes,Moderate,Serosa,Bad,8,1,349,Yes +344,hospital_3,Lev,70,Male,3089,Yes,No,No,Moderate,Serosa,Good,1,0,2723,No +345,hospital_2,Obs,70,Male,3089,NA,No,No,Poor,Serosa,Bad,1,1,775,Yes +346,hospital_2,Obs,71,Male,3088,No,No,No,Moderate,Serosa,Good,4,0,2326,Yes +347,hospital_4,Obs,59,Male,3087,No,No,No,Moderate,Serosa,Bad,2,1,1134,Yes +348,hospital_3,Lev,47,Male,3087,No,No,No,NA,Serosa,Bad,2,1,602,Yes +349,hospital_1,Lev,63,Male,3086,No,No,No,Poor,Serosa,Good,2,0,2547,No +350,hospital_3,Lev,69,Female,3085,No,No,No,Moderate,Serosa,Bad,7,1,940,No +351,hospital_1,Lev,73,Female,3084,No,No,No,Moderate,Serosa,Good,1,0,2496,No +352,hospital_1,Obs,67,Male,3083,No,No,No,Moderate,Serosa,Good,1,0,2628,No +353,hospital_1,Lev,55,Female,3083,No,No,No,Moderate,Serosa,Good,1,0,2353,No +354,hospital_2,Obs,45,Male,3081,No,No,No,Moderate,Serosa,Good,2,0,2184,Yes +355,hospital_3,Lev,78,Female,3080,Yes,No,No,Moderate,Serosa,Good,3,0,2219,Yes +356,hospital_2,Lev,80,Male,3079,No,No,No,Moderate,Serosa,Bad,3,1,191,Yes +357,hospital_3,Obs,55,Male,3076,No,No,No,Moderate,Serosa,Bad,8,1,421,No +358,hospital_2,Lev,64,Female,3076,Yes,No,No,Moderate,Serosa,Good,NA,0,2362,No +359,hospital_5,Lev,60,Female,3074,No,Yes,No,Moderate,Serosa,Bad,10,1,952,Yes +360,hospital_5,Lev,74,Female,3074,No,No,No,Moderate,Serosa,Bad,5,1,911,No +361,hospital_5,Lev,61,Female,3073,No,No,No,Moderate,Serosa,Good,1,1,1851,Yes +362,hospital_1,Obs,64,Male,3071,No,No,No,Moderate,Muscle,Good,4,0,2423,Yes +363,hospital_4,Obs,48,Female,3071,No,No,Yes,Poor,Serosa,Bad,1,1,464,Yes +364,hospital_5,Lev,76,Male,3070,No,No,No,Moderate,Serosa,Bad,2,1,443,No +365,hospital_3,Lev,76,Female,3070,No,No,No,Poor,Serosa,Bad,NA,1,186,Yes +366,hospital_1,Lev,50,Female,3070,No,No,No,Moderate,Serosa,Good,4,0,2545,Yes +367,hospital_5,Lev,56,Male,3069,No,No,No,Moderate,Adjacent structures,Bad,3,1,356,Yes +368,hospital_4,Lev,42,Female,3067,No,No,No,Poor,Serosa,Bad,10,1,484,No +369,hospital_2,Lev,72,Female,3067,No,No,No,Moderate,Serosa,Bad,1,1,382,No +370,hospital_5,Obs,68,Female,3065,No,No,Yes,Moderate,Serosa,Bad,9,1,1021,Yes +371,hospital_2,Lev,49,Male,3064,No,No,No,Moderate,Muscle,Good,1,0,2472,Yes +372,hospital_5,Lev,64,Male,3064,No,No,No,Moderate,Serosa,Good,12,0,2352,Yes +373,hospital_2,Obs,70,Female,3062,NA,No,No,Well,Muscle,Good,1,0,2486,Yes +374,hospital_2,Lev,50,Male,3062,No,No,Yes,Moderate,Adjacent structures,Bad,2,1,324,Yes +375,hospital_1,Obs,74,Male,3061,No,No,Yes,Poor,Serosa,Good,3,0,2517,Yes +376,hospital_4,Lev,37,Female,3058,No,No,No,Moderate,Serosa,Good,1,0,2613,No +377,hospital_2,Lev,75,Female,3057,NA,No,No,Poor,Serosa,Good,1,0,2450,Yes +378,hospital_5,Obs,56,Female,3056,No,No,No,Poor,Serosa,Bad,2,1,770,Yes +379,hospital_2,Lev,74,Male,3054,No,No,No,Well,Serosa,Good,3,0,2490,No +380,hospital_5,Obs,63,Male,3053,No,No,No,Moderate,Serosa,Bad,2,1,1548,Yes +381,hospital_3,Lev,56,Male,3052,No,No,No,Moderate,Muscle,Good,2,0,2449,Yes +382,hospital_5,Lev,42,Male,3052,No,No,No,Moderate,Serosa,Good,13,0,2299,No +383,hospital_2,Lev,63,Male,3049,No,No,No,Moderate,Serosa,Bad,NA,1,1252,Yes +384,hospital_2,Lev,62,Female,3048,No,No,No,Moderate,Serosa,Bad,2,1,730,Yes +385,hospital_1,Lev,33,Female,3047,No,No,No,Moderate,Serosa,Good,2,0,2460,Yes +386,hospital_5,Obs,50,Female,3047,No,No,No,Moderate,Serosa,Bad,8,1,499,Yes +387,hospital_5,Lev,73,Male,3044,No,No,No,Poor,Serosa,Bad,6,1,129,Yes +388,hospital_5,Lev,61,Female,3042,No,No,No,Poor,Serosa,Bad,9,1,52,Yes +389,hospital_3,Obs,70,Male,3039,Yes,Yes,No,Moderate,Serosa,Good,1,1,2171,Yes +390,hospital_3,Lev,38,Female,3038,No,No,No,Moderate,Serosa,Bad,3,1,1178,Yes +391,hospital_4,Obs,64,Female,3038,Yes,No,No,Moderate,Serosa,Good,3,1,1915,Yes +392,hospital_1,Lev,39,Female,3038,No,No,No,Moderate,Serosa,Good,2,0,2572,Yes +393,hospital_1,Lev,47,Female,3036,No,No,No,Moderate,Serosa,Good,1,0,2590,No +394,hospital_4,Obs,76,Male,3033,No,No,Yes,Poor,Serosa,Bad,13,1,215,Yes +395,hospital_2,Obs,65,Male,3032,No,No,No,Moderate,Serosa,Good,2,0,2325,Yes +396,hospital_3,Lev,43,Female,3030,Yes,No,No,Moderate,Serosa,Bad,4,1,961,Yes +397,hospital_3,Lev,72,Male,3030,No,No,No,Moderate,Serosa,Good,1,0,2691,Yes +398,hospital_3,Obs,33,Male,3029,No,No,No,Moderate,Serosa,Good,2,0,2574,Yes +399,hospital_4,Lev,66,Male,3028,No,No,No,Moderate,Serosa,Good,7,0,2540,Yes +400,hospital_1,Lev,74,Female,3027,No,No,No,Moderate,Serosa,Good,2,0,2364,No +401,hospital_1,Lev,54,Male,3026,No,No,No,Moderate,Serosa,Good,1,0,2472,Yes +402,hospital_5,Obs,44,Male,3022,No,No,No,Moderate,Serosa,Bad,14,1,409,No +403,hospital_5,Obs,75,Male,3022,Yes,No,No,Moderate,Muscle,Bad,27,1,961,No +404,hospital_4,Lev,58,Male,3020,No,No,No,Moderate,Serosa,Good,6,0,2449,Yes +405,hospital_1,Lev,48,Male,3020,No,No,No,Well,Muscle,Good,6,0,2520,Yes +406,hospital_3,Lev,64,Female,3018,No,No,No,Moderate,Serosa,Bad,1,1,916,No +407,hospital_2,Lev,49,Male,3017,NA,No,No,Well,Serosa,Good,1,0,2227,Yes +408,hospital_2,Obs,55,Female,3014,No,No,No,Moderate,Serosa,Good,1,0,2394,No +409,hospital_1,Lev,60,Male,3013,No,No,No,Moderate,Serosa,Bad,3,0,2029,No +410,hospital_3,Obs,67,Male,3011,No,No,No,Moderate,Serosa,Bad,2,0,2487,Yes +411,hospital_3,Lev,79,Male,3011,No,No,No,Moderate,Muscle,Bad,1,1,2052,No +412,hospital_1,Lev,57,Male,3011,No,No,No,Moderate,Serosa,Good,1,0,2690,Yes +413,hospital_2,Obs,22,Female,3010,No,No,No,Moderate,Serosa,Good,3,0,2234,Yes +414,hospital_5,Obs,59,Male,3007,Yes,No,No,Well,Serosa,Bad,4,1,537,No +415,hospital_2,Lev,66,Female,3003,Yes,No,No,Well,Serosa,Good,1,0,2277,Yes +416,hospital_2,Lev,54,Male,3001,No,No,Yes,Moderate,Adjacent structures,Bad,2,1,729,No +417,hospital_4,Obs,58,Male,3000,No,No,No,Moderate,Muscle,Good,1,0,2194,No +418,hospital_1,Obs,36,Female,2999,Yes,No,No,Moderate,Serosa,Good,7,0,2551,No +419,hospital_5,Obs,52,Male,2999,No,No,No,Moderate,Serosa,Bad,4,1,1692,Yes +420,hospital_5,Obs,61,Female,2997,No,No,No,Moderate,Serosa,Bad,1,1,758,Yes +421,hospital_4,Lev,76,Female,2993,No,No,No,Well,Serosa,Good,2,1,2079,No +422,hospital_3,Lev,58,Female,2993,No,No,Yes,Well,Serosa,Bad,6,1,720,Yes +423,hospital_3,Lev,52,Male,2985,No,No,No,Well,Serosa,Good,5,0,2380,Yes +424,hospital_4,Obs,72,Male,2984,No,No,No,Moderate,Serosa,Bad,1,1,845,Yes +425,hospital_4,Lev,74,Male,2983,No,No,No,Well,Serosa,Good,1,0,2416,Yes +426,hospital_4,Obs,62,Male,2979,No,No,No,Moderate,Muscle,Bad,6,1,863,Yes +427,hospital_2,Obs,46,Female,2977,No,No,Yes,Moderate,Serosa,Bad,1,1,1363,No +428,hospital_2,Obs,66,Male,2976,No,No,No,Moderate,Serosa,Good,1,0,2528,No +429,hospital_2,Lev,52,Male,2976,No,No,No,Moderate,Serosa,Bad,5,1,1145,Yes +430,hospital_5,Lev,38,Female,2976,No,No,No,NA,Serosa,Bad,24,1,499,Yes +431,hospital_4,Obs,61,Male,2976,No,No,No,Moderate,Serosa,Bad,1,1,242,Yes +432,hospital_1,Obs,60,Female,2972,No,No,No,Well,Serosa,Good,1,0,2294,Yes +433,hospital_2,Lev,68,Female,2970,No,No,Yes,Well,Serosa,Bad,2,1,858,Yes +434,hospital_5,Lev,53,Female,2966,No,No,No,Moderate,Serosa,Bad,6,1,122,No +435,hospital_3,Lev,58,Male,2966,No,No,No,Moderate,Serosa,Bad,1,0,2682,Yes +436,hospital_3,Obs,64,Male,2966,No,No,No,Moderate,Serosa,Bad,4,1,1818,Yes +437,hospital_1,Obs,68,Male,2965,Yes,No,Yes,Moderate,Serosa,Good,3,0,2532,Yes +438,hospital_2,Obs,62,Male,2958,No,No,Yes,Moderate,Adjacent structures,Bad,6,1,331,Yes +439,hospital_2,Obs,70,Male,2955,No,No,No,Well,Serosa,Bad,1,1,1048,No +440,hospital_3,Lev,57,Male,2952,No,No,No,Moderate,Serosa,Good,1,0,2513,Yes +441,hospital_1,Lev,66,Female,2950,No,No,Yes,Moderate,Adjacent structures,Bad,1,1,340,Yes +442,hospital_3,Lev,59,Female,2947,NA,No,No,Moderate,Serosa,Good,11,1,1850,Yes +443,hospital_1,Lev,75,Male,2943,No,No,No,Well,Serosa,Good,3,0,2332,Yes +444,hospital_3,Lev,77,Male,2930,No,No,No,Moderate,Serosa,Good,2,0,2279,Yes +445,hospital_5,Lev,57,Male,2929,No,No,No,Moderate,Serosa,Bad,6,1,1041,Yes +446,hospital_3,Obs,72,Male,2925,No,No,No,Well,Muscle,Bad,2,1,1790,No +447,hospital_3,Lev,64,Female,2923,Yes,No,No,Moderate,Serosa,Bad,3,1,304,Yes +448,hospital_2,Lev,33,Male,2923,No,No,No,Poor,Serosa,Bad,2,0,2517,Yes +449,hospital_3,Lev,62,Female,2921,No,No,No,Moderate,Serosa,Bad,2,0,2156,Yes +450,hospital_4,Lev,70,Male,2920,No,No,No,Moderate,Serosa,Bad,1,1,1388,Yes +451,hospital_2,Lev,55,Female,2918,Yes,No,No,Well,Serosa,Good,4,0,2544,Yes +452,hospital_2,Obs,32,Male,2908,Yes,No,Yes,Moderate,Serosa,Good,11,0,1852,No +453,hospital_2,Obs,64,Female,2908,Yes,No,No,Moderate,Muscle,Good,2,0,2122,Yes +454,hospital_1,Obs,48,Female,2906,No,No,No,Moderate,Adjacent structures,Good,1,0,2577,Yes +455,hospital_4,Lev,68,Male,2906,No,No,Yes,Moderate,Serosa,Good,3,1,2023,No +456,hospital_2,Lev,59,Female,2901,No,No,No,Moderate,Serosa,Bad,1,1,1201,Yes +457,hospital_4,Obs,68,Male,2897,No,No,Yes,Poor,Serosa,Bad,9,1,901,Yes +458,hospital_3,Lev,50,Female,2895,No,No,Yes,Well,Serosa,Good,1,0,2385,Yes +459,hospital_2,Obs,41,Female,2895,Yes,No,No,Moderate,Serosa,Bad,4,1,663,Yes +460,hospital_2,Lev,69,Female,2892,No,No,Yes,Moderate,Serosa,Good,1,0,2506,Yes +461,hospital_1,Lev,46,Male,2890,No,No,No,Well,Muscle,Good,2,0,2332,Yes +462,hospital_4,Obs,43,Male,2885,No,No,No,Moderate,Serosa,Good,1,0,2176,Yes +463,hospital_3,Lev,68,Male,2881,No,No,No,Poor,Serosa,Bad,3,1,1212,No +464,hospital_4,Lev,73,Male,2880,No,No,No,Moderate,Serosa,Bad,3,1,890,No +465,hospital_5,Lev,66,Female,2876,No,No,Yes,Poor,Adjacent structures,Bad,4,1,302,Yes +466,hospital_1,Obs,60,Female,2876,No,No,Yes,Moderate,Serosa,Good,1,0,2396,Yes +467,hospital_1,Lev,74,Male,2871,No,No,No,Moderate,Serosa,Good,2,0,2481,No +468,hospital_5,Lev,68,Male,2869,No,No,No,Well,Serosa,Bad,1,1,316,Yes +469,hospital_1,Lev,60,Female,2868,Yes,No,No,Moderate,Serosa,Good,1,0,2245,Yes +470,hospital_2,Obs,71,Male,2864,No,No,Yes,Moderate,Adjacent structures,Good,1,0,2447,No +471,hospital_3,Obs,76,Male,2850,No,No,No,Moderate,Submucosa,Good,2,0,2213,Yes +472,hospital_5,Obs,57,Male,2844,No,No,No,Poor,Muscle,Bad,8,1,1070,Yes +473,hospital_4,Lev,33,Female,3102.4,No,No,No,Poor,Serosa,Bad,7,1,439,Yes +474,hospital_3,Lev,54,Male,3096,No,No,No,Moderate,Serosa,Bad,4,1,905,No +475,hospital_5,Obs,68,Male,3091.2,No,No,No,Moderate,Serosa,Bad,13,1,1723,Yes +476,hospital_5,Obs,70,Female,3086.4,No,No,No,Poor,Muscle,Bad,6,1,241,Yes +477,hospital_5,Obs,66,Male,3086.4,No,No,No,Moderate,Serosa,Bad,5,1,1314,No +478,hospital_5,Lev,45,Female,3068.8,Yes,No,No,Moderate,Serosa,Bad,3,1,438,Yes +479,hospital_1,Lev,61,Female,3068.8,No,No,No,Moderate,Serosa,Good,2,0,1981,Yes +480,hospital_1,Obs,74,Female,3064,No,No,Yes,Poor,Serosa,Good,1,0,2195,Yes +481,hospital_4,Obs,47,Male,3060.8,Yes,Yes,Yes,Moderate,Serosa,Bad,4,1,1101,Yes +482,hospital_5,Lev,58,Female,3051.2,Yes,No,No,Poor,Serosa,Bad,5,1,79,Yes +483,hospital_5,Obs,73,Male,3048,No,No,No,Moderate,Serosa,Bad,1,1,976,Yes +484,hospital_5,Lev,61,Male,3048,No,No,No,Moderate,Serosa,Bad,17,1,664,No +485,hospital_4,Obs,44,Female,3043.2,No,No,No,Moderate,Serosa,Good,4,0,2299,Yes +486,hospital_4,Lev,56,Male,3043.2,No,No,No,Moderate,Serosa,Bad,1,1,279,Yes +487,hospital_5,Lev,66,Female,3033.6,No,No,No,Moderate,Serosa,Bad,7,1,1037,Yes +488,hospital_5,Obs,30,Female,3025.6,No,No,No,Poor,Serosa,Bad,6,1,692,Yes +489,hospital_5,Lev,67,Female,3016,No,No,Yes,Moderate,Serosa,Good,10,1,2174,No +490,hospital_1,Lev,74,Female,3014.4,No,No,No,Moderate,Serosa,Good,2,0,2144,No +491,hospital_4,Lev,74,Female,3006.4,No,No,Yes,Poor,Serosa,Good,1,0,2058,Yes +492,hospital_4,Obs,56,Male,3006.4,No,No,No,Moderate,Serosa,Good,4,0,2485,Yes +493,hospital_1,Lev,60,Female,3000,No,No,No,Moderate,Serosa,Good,2,0,2410,Yes +494,hospital_1,Lev,54,Female,3000,Yes,No,Yes,Poor,Muscle,Good,2,0,2565,Yes +495,hospital_5,Lev,74,Female,2992,No,No,No,Moderate,Muscle,Bad,3,1,884,No +496,hospital_3,Lev,45,Female,2982.4,No,No,No,Moderate,Serosa,Bad,3,1,389,Yes +497,hospital_5,Lev,81,Female,2977.6,No,No,No,Moderate,Serosa,Bad,1,1,692,Yes +498,hospital_4,Lev,73,Male,2969.6,Yes,No,No,Moderate,Serosa,Bad,1,1,642,Yes +499,hospital_3,Lev,71,Male,2969.6,Yes,No,No,Moderate,Serosa,Bad,1,1,846,Yes +500,hospital_1,Lev,70,Male,2968,No,No,No,NA,Serosa,Good,3,0,2203,No +501,hospital_2,Lev,66,Male,2964.8,No,No,No,Moderate,Serosa,Bad,1,0,2164,Yes +502,hospital_3,Lev,71,Female,2963.2,No,No,No,Moderate,Serosa,Bad,NA,1,1273,Yes +503,hospital_3,Obs,48,Male,2961.6,No,No,No,Poor,Muscle,Bad,1,0,2393,Yes +504,hospital_4,Lev,55,Female,2960,No,No,No,Moderate,Serosa,Bad,4,1,862,No +505,hospital_1,Lev,72,Female,2942.4,No,No,No,Poor,Muscle,Good,2,0,2331,Yes +506,hospital_4,Lev,57,Male,2940.8,No,No,No,NA,Serosa,Good,3,0,2264,Yes +507,hospital_5,Lev,57,Male,2929.6,No,No,No,Poor,Serosa,Bad,11,1,144,No +508,hospital_1,Obs,38,Male,2926.4,No,No,No,Well,Serosa,Good,2,0,2429,Yes +509,hospital_2,Lev,52,Male,2924.8,Yes,No,No,Moderate,Serosa,Bad,0,1,723,Yes +510,hospital_2,Obs,57,Male,2923.2,No,No,No,Moderate,Serosa,Good,1,0,2530,Yes +511,hospital_4,Lev,33,Female,2923.2,No,No,No,Moderate,Serosa,Bad,2,1,1568,No +512,hospital_1,Obs,39,Female,2916.8,No,No,No,Moderate,Muscle,Good,2,0,2292,Yes +513,hospital_2,Lev,61,Male,2916.8,No,No,No,Moderate,Serosa,Good,1,0,2252,Yes +514,hospital_1,Lev,71,Female,2912,No,No,No,Poor,Serosa,Good,1,0,2408,No +515,hospital_3,Lev,58,Male,2910.4,No,No,No,Moderate,Serosa,Good,4,0,2555,No +516,hospital_3,Lev,66,Female,2908.8,No,No,No,Poor,Serosa,Bad,7,1,276,Yes +517,hospital_3,Obs,59,Female,2902.4,No,No,No,Moderate,Muscle,Good,4,1,1896,Yes +518,hospital_3,Lev,43,Female,2902.4,Yes,No,No,Moderate,Serosa,Good,1,0,2147,Yes +519,hospital_3,Obs,66,Male,2899.2,No,No,No,Moderate,Serosa,Good,3,0,2269,No +520,hospital_3,Obs,48,Female,2884.8,No,No,No,Moderate,Serosa,Good,1,0,2391,Yes +521,hospital_5,Lev,68,Male,2880,No,No,No,Moderate,Serosa,Bad,1,1,1424,Yes +522,hospital_2,Obs,72,Female,2876.8,No,No,No,Moderate,Serosa,Good,NA,0,2257,Yes +523,hospital_3,Lev,77,Female,2867.2,NA,No,No,Poor,Adjacent structures,Good,10,0,2381,Yes +524,hospital_1,Lev,68,Female,2864,Yes,No,No,Moderate,Serosa,Good,1,0,2103,Yes +525,hospital_4,Obs,44,Female,2860.8,No,No,Yes,Moderate,Adjacent structures,Good,1,0,2210,Yes +526,hospital_1,Lev,63,Female,2852.8,No,No,No,Moderate,Serosa,Good,1,0,2530,No +527,hospital_1,Lev,66,Male,2835.2,No,No,No,Moderate,Serosa,Good,1,0,2386,Yes +528,hospital_5,Lev,50,Male,2828.8,No,No,No,Poor,Serosa,Bad,3,1,219,Yes +529,hospital_3,Lev,72,Male,2827.2,No,No,No,Moderate,Serosa,Bad,1,1,486,No +530,hospital_4,Lev,40,Male,2803.2,No,No,No,Well,Serosa,Bad,5,1,1246,Yes +531,hospital_4,Lev,49,Male,2792,No,No,No,Moderate,Serosa,Good,10,0,2138,Yes +532,hospital_1,Lev,56,Female,2756.8,No,No,No,Poor,Serosa,Good,2,0,2439,No +533,hospital_4,Obs,61,Male,2734.4,No,No,No,Moderate,Muscle,Good,2,0,2231,Yes +534,hospital_5,Obs,65,Male,2707.2,No,No,No,Moderate,Serosa,Bad,6,1,384,Yes +535,hospital_3,Lev,65,Male,2686.4,No,No,No,Moderate,Muscle,Good,2,0,2505,Yes +536,hospital_5,Lev,72,Female,2673.6,No,No,No,Well,Submucosa,Bad,1,1,1652,Yes +537,hospital_1,Lev,68,Female,2668.8,No,No,Yes,Moderate,Serosa,Good,1,0,2441,No +538,hospital_4,Obs,59,Female,2649.6,No,No,No,Moderate,Serosa,Bad,4,1,687,No +539,hospital_4,Lev,59,Male,2643.2,No,No,No,Moderate,Serosa,Good,4,0,2179,Yes +540,hospital_2,Lev,71,Female,2619.2,Yes,No,No,Moderate,Serosa,Good,6,0,2189,Yes +541,hospital_3,Lev,49,Male,2592,No,No,No,Moderate,Serosa,Good,8,0,2472,Yes +542,hospital_1,Lev,70,Male,2571.2,No,No,No,Moderate,Serosa,Good,3,0,2111,Yes +543,hospital_3,Lev,55,Male,2508.8,No,No,No,Poor,Serosa,Good,7,0,2020,Yes +544,hospital_4,Lev,46,Female,2480,No,Yes,No,Moderate,Serosa,Bad,7,1,1161,Yes +545,hospital_1,Obs,77,Male,2476.8,No,No,No,Moderate,Serosa,Good,1,0,2231,Yes +546,hospital_2,Lev,57,Male,2476.8,No,No,No,Moderate,Serosa,Good,4,0,2300,Yes +547,hospital_3,Obs,68,Male,2464,No,No,No,Moderate,Serosa,Good,1,0,2391,Yes +548,hospital_2,Lev,62,Male,2459.2,No,No,Yes,Moderate,Serosa,Bad,1,1,759,No +549,hospital_2,Obs,44,Male,2448,No,No,No,Poor,Serosa,Bad,7,1,166,No +550,hospital_1,Lev,58,Female,2433.6,No,No,Yes,Moderate,Serosa,Good,1,0,2323,Yes +551,hospital_3,Lev,75,Female,2417.6,No,No,No,Well,Serosa,Good,2,0,2321,Yes +552,hospital_1,Obs,70,Female,2414.4,Yes,No,No,Moderate,Serosa,Good,7,0,1976,Yes +553,hospital_4,Obs,82,Male,2392,No,No,No,Moderate,Serosa,Good,6,0,2229,No +554,hospital_3,Lev,61,Female,2371.2,No,No,No,Moderate,Serosa,Bad,3,1,1671,Yes +555,hospital_2,Obs,52,Male,2358.4,No,No,No,Moderate,Serosa,Good,2,1,1907,Yes +556,hospital_4,Lev,47,Male,2315.2,No,No,No,Poor,Serosa,Bad,7,1,1783,Yes +557,hospital_4,Lev,61,Female,2313.6,No,No,No,Poor,Serosa,Bad,7,1,684,Yes +558,hospital_3,Lev,39,Male,2302.4,No,No,No,Moderate,Serosa,Bad,9,1,441,Yes +559,hospital_2,Lev,69,Female,2299.2,No,No,No,Moderate,Muscle,Bad,3,1,902,No +560,hospital_4,Lev,55,Male,2294.4,No,No,No,Poor,Serosa,Good,7,0,2244,Yes +561,hospital_1,Obs,56,Female,2294.4,Yes,No,No,Moderate,Serosa,Good,1,0,2170,Yes +562,hospital_3,Obs,80,Male,2278.4,No,No,No,Poor,Serosa,Good,1,0,1870,No +563,hospital_3,Lev,43,Male,2273.6,No,No,No,Moderate,Serosa,Good,4,0,2066,No +564,hospital_4,Lev,83,Male,2248,No,No,No,Moderate,Serosa,Good,2,0,2030,Yes +565,hospital_4,Obs,85,Female,2238.4,No,No,No,Well,Serosa,Bad,1,1,253,Yes +566,hospital_1,Lev,61,Male,2220.8,No,No,No,Moderate,Serosa,Good,1,0,2047,No +567,hospital_3,Lev,47,Female,2219.2,No,No,No,Moderate,Adjacent structures,Bad,9,1,1768,Yes +568,hospital_4,Lev,76,Female,2200,No,No,No,Moderate,Serosa,Good,1,0,2043,Yes +569,hospital_2,Lev,58,Male,2184,No,No,No,Moderate,Serosa,Good,1,0,2162,Yes +570,hospital_1,Obs,59,Male,2180.8,No,No,No,Moderate,Muscle,Good,2,0,2093,Yes +571,hospital_4,Lev,60,Female,2123.2,No,No,No,Moderate,Serosa,Good,1,0,2310,No +572,hospital_4,Lev,32,Male,2120,No,No,No,Moderate,Serosa,Good,2,1,2128,No +573,hospital_5,Obs,56,Male,2102.4,No,No,No,NA,Adjacent structures,Good,1,1,1884,No +574,hospital_5,Lev,75,Male,2100.8,No,No,No,Moderate,Serosa,Bad,2,1,219,No +575,hospital_4,Lev,62,Male,2089.6,No,No,No,Well,Serosa,Good,3,0,2309,No +576,hospital_4,Obs,69,Female,2086.4,No,No,No,Moderate,Serosa,Bad,12,1,313,Yes +577,hospital_5,Lev,72,Male,2083.2,No,No,Yes,Moderate,Serosa,Bad,4,1,546,Yes +578,hospital_2,Obs,54,Female,2072,No,No,No,Moderate,Serosa,Good,1,1,2213,Yes +579,hospital_5,Lev,72,Male,2072,No,No,No,Moderate,Serosa,Good,1,1,1856,No +580,hospital_2,Lev,27,Female,2064,No,No,No,Moderate,Serosa,NA,1,0,1421,No +581,hospital_4,Lev,62,Female,2046.4,No,No,No,Moderate,Adjacent structures,Bad,4,1,460,Yes +582,hospital_1,Lev,39,Female,2046.4,No,No,No,Moderate,Submucosa,Good,2,0,2173,No +583,hospital_5,Lev,60,Female,2041.6,No,No,No,Moderate,Serosa,Bad,4,1,283,Yes +584,hospital_2,Lev,55,Male,2041.6,Yes,No,No,Poor,Serosa,Bad,5,1,34,Yes +585,hospital_1,Obs,64,Male,2036.8,No,No,No,Moderate,Serosa,Good,1,0,2191,Yes +586,hospital_3,Lev,68,Female,2035.2,No,No,No,Poor,Serosa,Good,12,0,2186,No +587,hospital_3,Obs,65,Female,2019.2,No,No,No,Moderate,Serosa,Bad,2,1,1159,Yes +588,hospital_4,Lev,66,Female,2019.2,Yes,No,No,Well,Serosa,Bad,3,1,616,Yes +589,hospital_1,Lev,39,Male,2003.2,No,No,No,Poor,Serosa,Good,2,0,2270,Yes +590,hospital_1,Lev,54,Male,1993.6,No,No,Yes,Moderate,Serosa,Bad,NA,1,1061,No +591,hospital_5,Obs,34,Male,1993.6,Yes,No,No,Moderate,Serosa,Bad,1,1,591,No +592,hospital_4,Lev,74,Female,1979.2,No,No,No,Moderate,Serosa,Good,4,0,2065,Yes +593,hospital_2,Obs,81,Female,1968,Yes,No,Yes,Moderate,Serosa,Bad,3,1,208,Yes +594,hospital_1,Lev,38,Male,1950.4,No,No,No,Moderate,Serosa,Good,1,0,2360,Yes +595,hospital_2,Lev,59,Female,1945.6,No,No,No,Moderate,Serosa,Good,3,0,2312,Yes +596,hospital_2,Lev,62,Female,1944,No,No,No,Moderate,Serosa,Good,1,0,1902,Yes +597,hospital_2,Lev,61,Male,1939.2,Yes,No,No,Well,Muscle,NA,5,0,1814,Yes +598,hospital_1,Obs,46,Male,1934.4,Yes,No,No,Moderate,Serosa,Good,2,0,2111,No +599,hospital_1,Lev,55,Male,1931.2,No,No,No,Moderate,Serosa,Good,1,0,2330,Yes +600,hospital_4,Obs,57,Male,1921.6,No,No,No,Moderate,Serosa,Good,5,0,2202,Yes +601,hospital_4,Lev,38,Female,1916.8,No,No,No,Moderate,Serosa,Bad,3,1,1295,No +602,hospital_5,Lev,69,Female,1912,No,No,Yes,Moderate,Serosa,Good,19,0,1918,Yes +603,hospital_4,Obs,79,Female,1908.8,No,No,Yes,Moderate,Muscle,Good,6,0,2066,Yes +604,hospital_4,Lev,71,Female,1905.6,No,No,No,Moderate,Serosa,Good,2,0,2136,No +605,hospital_2,Lev,74,Male,1897.6,No,No,No,Poor,Serosa,Good,1,0,2289,Yes +606,hospital_4,Lev,30,Female,1884.8,Yes,No,No,Moderate,Serosa,Bad,12,1,576,Yes +607,hospital_1,Obs,72,Female,1884.8,No,No,No,Poor,Serosa,Good,1,0,2232,Yes +608,hospital_5,Lev,68,Female,1865.6,NA,No,No,Moderate,Serosa,Bad,3,1,1034,Yes +609,hospital_2,Lev,66,Male,1857.6,Yes,No,No,Poor,Submucosa,Bad,NA,1,583,Yes +610,hospital_5,Obs,63,Male,1854.4,No,No,No,Moderate,Serosa,Bad,4,1,417,Yes +611,hospital_3,Lev,52,Female,1846.4,No,No,Yes,Moderate,Serosa,Good,1,0,1905,Yes +612,hospital_4,Lev,64,Male,1841.6,No,No,No,Moderate,Serosa,Bad,4,1,875,Yes +613,hospital_5,Lev,68,Male,1832,No,No,No,Moderate,Serosa,Bad,1,1,674,Yes +614,hospital_3,Lev,74,Male,1832,No,No,No,Moderate,Serosa,Good,2,0,2185,Yes +615,hospital_5,Lev,32,Male,1822.4,No,No,No,Moderate,Serosa,Bad,2,1,1151,No +616,hospital_4,Lev,60,Female,1820.8,Yes,No,No,Moderate,Serosa,Bad,6,1,342,Yes +617,hospital_5,Obs,39,Female,1817.6,No,No,No,Moderate,Serosa,Good,8,0,2187,Yes +618,hospital_5,Obs,76,Female,1816,No,No,Yes,Moderate,Serosa,Bad,5,1,1434,Yes +619,hospital_5,Lev,62,Male,1814.4,No,No,No,Poor,Serosa,Bad,14,1,430,Yes +620,hospital_4,Lev,41,Female,1812.8,No,No,Yes,Moderate,Serosa,Good,2,0,2339,Yes +621,hospital_5,Lev,35,Male,1795.2,No,No,Yes,Moderate,Serosa,Bad,2,1,1365,Yes +622,hospital_4,Obs,59,Female,1787.2,No,No,No,Moderate,Serosa,Good,1,0,2313,No +623,hospital_3,Obs,52,Male,1779.2,No,No,No,Moderate,Serosa,Good,2,0,2153,Yes +624,hospital_2,Lev,65,Male,1768,No,No,No,Moderate,Serosa,Good,1,0,2164,No +625,hospital_3,Lev,61,Male,1764.8,No,No,No,Poor,Serosa,Good,3,0,2180,No +626,hospital_4,Obs,61,Male,1761.6,No,No,No,Well,Serosa,Good,8,0,2110,Yes +627,hospital_1,Obs,59,Male,1747.2,No,No,No,Well,Serosa,Good,1,0,2139,Yes +628,hospital_1,Lev,59,Male,1732.8,No,No,No,NA,Serosa,Good,2,0,2120,No +629,hospital_3,Lev,71,Female,1726.4,No,No,No,Moderate,Muscle,Good,5,1,2197,Yes +630,hospital_2,Obs,39,Male,1712,No,No,No,Poor,Adjacent structures,NA,4,0,453,No +631,hospital_4,Obs,65,Male,1697.6,No,No,No,Poor,Serosa,Bad,7,1,928,No +632,hospital_2,Lev,34,Female,1688,Yes,No,No,Well,Serosa,Bad,3,1,675,Yes +633,hospital_1,Obs,51,Male,1676.8,Yes,No,No,Moderate,Serosa,Good,4,0,2170,No +634,hospital_3,Obs,55,Female,1673.6,No,No,No,Moderate,Serosa,Good,3,0,2138,Yes +635,hospital_4,Lev,65,Male,1665.6,No,Yes,No,Poor,Serosa,Good,3,0,2255,Yes +636,hospital_1,Lev,71,Female,1659.2,No,No,No,Well,Serosa,Good,NA,0,2290,No +637,hospital_2,Lev,68,Female,1654.4,Yes,No,No,Moderate,Serosa,Bad,1,1,1055,Yes +638,hospital_2,Lev,59,Female,1649.6,No,No,No,Moderate,Serosa,Good,1,0,2347,No +639,hospital_4,Lev,66,Male,1635.2,No,No,No,Poor,Serosa,Bad,2,1,573,No +640,hospital_4,Obs,62,Male,1633.6,No,No,No,Moderate,Muscle,Good,2,0,2200,No +641,hospital_5,Lev,40,Female,1628.8,No,No,No,Moderate,Serosa,Bad,8,1,550,Yes +642,hospital_5,Lev,64,Male,1595.2,No,No,No,Poor,Serosa,Bad,3,1,1405,Yes +643,hospital_4,Lev,40,Male,1595.2,Yes,No,No,Poor,Serosa,Good,2,0,2355,No +644,hospital_4,Lev,70,Male,1588.8,No,No,No,Moderate,Serosa,Bad,9,1,1186,Yes +645,hospital_2,Lev,66,Male,1577.6,No,No,Yes,NA,Adjacent structures,Bad,1,1,1540,Yes +646,hospital_3,Lev,73,Male,1563.2,Yes,No,Yes,Moderate,Muscle,Good,1,0,2229,Yes +647,hospital_3,Lev,69,Male,1561.6,No,No,No,Well,Serosa,Bad,1,1,969,Yes +648,hospital_3,Obs,58,Male,1550.4,No,No,No,Moderate,Serosa,Bad,1,1,465,Yes +649,hospital_4,Lev,55,Female,1548.8,No,No,No,Moderate,Serosa,Bad,6,1,603,No +650,hospital_5,Lev,53,Female,1545.6,No,No,Yes,Moderate,Serosa,Bad,6,1,997,No +651,hospital_1,Lev,52,Male,1540.8,No,No,No,Moderate,Serosa,Good,2,0,2274,Yes +652,hospital_3,Obs,62,Female,1537.6,No,No,No,Moderate,Serosa,Bad,3,1,563,Yes +653,hospital_3,Lev,61,Male,1537.6,No,No,Yes,Moderate,Serosa,Bad,2,1,1434,Yes +654,hospital_4,Lev,69,Female,1537.6,No,No,No,Moderate,Serosa,Good,3,0,2316,Yes +655,hospital_5,Lev,41,Female,1537.6,Yes,No,No,Moderate,Serosa,Bad,3,1,692,Yes +656,hospital_5,Obs,64,Male,1531.2,No,No,No,Moderate,Serosa,Bad,3,1,1447,No +657,hospital_5,Lev,59,Female,1523.2,No,No,No,Poor,Serosa,Bad,3,1,428,Yes +658,hospital_2,Lev,65,Female,1518.4,No,No,No,Well,Muscle,Good,1,0,2152,Yes +659,hospital_4,Obs,66,Male,1510.4,No,No,No,Moderate,Serosa,Bad,3,1,854,Yes +660,hospital_1,Lev,60,Male,1507.2,No,No,No,Moderate,Serosa,Good,2,0,2093,Yes +661,hospital_2,Lev,43,Male,1504,No,No,Yes,Moderate,Serosa,Good,1,0,2198,No +662,hospital_2,Obs,74,Male,1502.4,No,No,No,Poor,Serosa,Good,1,0,2126,Yes +663,hospital_1,Lev,67,Male,1500.8,No,No,No,Poor,Muscle,Good,2,0,2189,Yes +664,hospital_1,Lev,46,Male,1497.6,Yes,No,No,Moderate,Serosa,Good,1,0,2142,Yes +665,hospital_2,Lev,47,Male,1486.4,No,No,No,Moderate,Muscle,Good,3,0,2278,Yes +666,hospital_3,Obs,66,Male,1484.8,Yes,No,No,Moderate,Serosa,Bad,4,1,622,Yes +667,hospital_2,Lev,36,Female,1478.4,Yes,No,No,Moderate,Serosa,Good,6,0,2192,Yes +668,hospital_3,Obs,62,Male,1465.6,Yes,No,No,Poor,Serosa,Bad,2,1,413,No +669,hospital_5,Lev,69,Female,1457.6,No,No,No,Moderate,Serosa,Bad,2,1,1191,Yes +670,hospital_3,Obs,76,Female,1454.4,No,No,No,Well,Serosa,Bad,3,1,1139,Yes +671,hospital_5,Lev,36,Male,1448,Yes,No,No,Poor,Serosa,Bad,2,1,165,Yes +672,hospital_1,Obs,73,Male,1448,No,No,Yes,NA,Muscle,Good,3,0,2210,Yes +673,hospital_3,Obs,72,Male,1443.2,No,No,No,Moderate,Muscle,Good,5,0,2227,Yes +674,hospital_4,Lev,61,Male,1441.6,No,No,No,Moderate,Muscle,Good,1,0,2076,No +675,hospital_1,Obs,58,Male,1424,No,No,No,Moderate,Serosa,Good,2,0,2132,Yes +676,hospital_2,Lev,52,Female,1419.2,Yes,No,No,Well,Serosa,Good,3,0,2084,Yes +677,hospital_3,Obs,66,Male,1419.2,No,No,No,Moderate,Adjacent structures,Good,2,0,1905,No +678,hospital_3,Lev,43,Female,1419.2,No,No,No,Moderate,Serosa,Bad,7,1,608,Yes +679,hospital_1,Lev,60,Male,1416,No,No,No,Moderate,Muscle,Good,1,0,2066,Yes +680,hospital_3,Obs,61,Female,1414.4,No,No,No,Moderate,Serosa,Good,4,0,2006,Yes +681,hospital_4,Lev,61,Male,1412.8,No,No,No,Moderate,Muscle,Good,3,0,2183,Yes +682,hospital_2,Lev,46,Male,1400,No,No,No,Moderate,Submucosa,Good,1,0,2099,Yes +683,hospital_3,Lev,73,Male,1398.4,No,No,No,Moderate,Serosa,Good,1,0,1879,Yes +684,hospital_4,Obs,65,Female,1380.8,Yes,No,No,Moderate,Serosa,Bad,3,1,264,Yes +685,hospital_2,Lev,61,Female,1379.2,Yes,No,No,Moderate,Serosa,Good,1,0,2107,No +686,hospital_5,Lev,65,Male,1372.8,No,No,No,Poor,Serosa,Bad,15,1,743,No +687,hospital_3,Obs,68,Male,1366.4,No,No,No,Moderate,Serosa,Bad,2,1,966,Yes +688,hospital_4,Lev,63,Male,1353.6,No,No,No,Moderate,Serosa,Good,1,0,2076,Yes +689,hospital_5,Lev,72,Male,1352,Yes,No,No,Poor,Serosa,Bad,4,1,24,No +690,hospital_4,Lev,74,Female,1350.4,No,Yes,No,Moderate,Serosa,Bad,2,1,448,Yes +691,hospital_5,Lev,45,Female,1344,No,No,No,Moderate,Serosa,Bad,9,1,909,Yes +692,hospital_3,Lev,66,Female,1332.8,No,No,No,Well,Serosa,Good,1,0,2188,No +693,hospital_3,Obs,38,Male,1332.8,NA,No,No,NA,Adjacent structures,Bad,2,1,469,Yes +694,hospital_2,Obs,46,Female,1331.2,No,Yes,Yes,Poor,Adjacent structures,Bad,2,1,594,Yes +695,hospital_1,Lev,51,Female,1297.6,No,No,No,Moderate,Serosa,Good,1,0,2008,Yes +696,hospital_2,Lev,65,Male,1289.6,No,No,No,Moderate,Adjacent structures,Bad,3,1,1276,No +697,hospital_3,Obs,55,Male,1289.6,No,No,No,Moderate,Serosa,Bad,2,1,957,Yes +698,hospital_4,Obs,58,Male,1283.2,No,No,No,Moderate,Serosa,Good,4,1,1950,Yes +699,hospital_1,Lev,65,Male,1283.2,No,No,No,Moderate,Serosa,Good,1,0,2668,No +700,hospital_1,Lev,46,Female,1275.2,Yes,No,No,Well,Serosa,Good,2,0,2250,Yes +701,hospital_1,Lev,57,Female,1272,No,No,No,Moderate,Serosa,Good,1,0,2191,Yes +702,hospital_2,Obs,67,Male,1240,No,No,Yes,Moderate,Serosa,Good,1,0,2365,Yes +703,hospital_1,Lev,75,Female,1238.4,No,No,No,Moderate,Serosa,Good,1,0,2331,Yes +704,hospital_5,Lev,64,Male,1232,No,No,Yes,Moderate,Serosa,Bad,5,1,1262,Yes +705,hospital_2,Lev,63,Male,1225.6,No,No,No,Moderate,Serosa,NA,2,0,1537,Yes +706,hospital_1,Lev,64,Male,1224,No,No,No,Moderate,Serosa,Good,3,0,2387,No +707,hospital_1,Obs,59,Male,1222.4,No,No,No,Moderate,Serosa,Bad,1,0,2235,Yes +708,hospital_3,Lev,78,Female,1217.6,No,No,No,Moderate,Serosa,Bad,3,0,1980,Yes +709,hospital_4,Lev,63,Male,1216,No,No,No,Well,Submucosa,Bad,2,1,578,Yes +710,hospital_3,Obs,57,Male,1214.4,No,No,No,Well,Serosa,Bad,4,1,1083,Yes +711,hospital_5,Obs,52,Male,1214.4,No,No,No,Moderate,Serosa,Good,3,1,1875,No +712,hospital_1,Obs,50,Female,1212.8,No,No,No,Moderate,Serosa,Good,3,0,2384,No +713,hospital_2,Obs,36,Male,1208,Yes,No,No,Moderate,Serosa,Bad,3,1,563,Yes +714,hospital_1,Lev,50,Female,1204.8,No,No,No,Poor,Serosa,Good,4,0,2076,Yes +715,hospital_1,Obs,53,Male,1188.8,No,No,No,Moderate,Serosa,Good,1,0,2025,Yes +716,hospital_4,Lev,48,Male,1188.8,No,No,No,Moderate,Serosa,Good,7,0,2055,Yes +717,hospital_3,Obs,55,Female,1182.4,No,No,No,Moderate,Serosa,Bad,2,1,1375,No +718,hospital_2,Lev,47,Male,1177.6,No,No,No,Moderate,Muscle,Good,2,0,2350,Yes +719,hospital_1,Lev,74,Female,1168,No,No,Yes,Moderate,Serosa,Good,1,0,2200,Yes +720,hospital_3,Lev,53,Male,1166.4,Yes,Yes,No,Moderate,Serosa,Good,3,0,2222,Yes +721,hospital_2,Obs,55,Male,1156.8,No,No,No,Moderate,Serosa,Good,7,0,2149,Yes +722,hospital_3,Lev,53,Male,1153.6,No,No,No,Moderate,Muscle,Good,4,0,2303,No +723,hospital_3,Obs,67,Male,1152,No,Yes,No,Moderate,Adjacent structures,Bad,4,1,322,Yes +724,hospital_5,Lev,56,Male,1148.8,No,No,No,Moderate,Serosa,Bad,3,1,764,Yes +725,hospital_3,Lev,30,Female,1147.2,Yes,No,Yes,Moderate,Serosa,Bad,1,1,765,Yes +726,hospital_5,Lev,56,Female,1145.6,No,No,No,Well,Serosa,Bad,8,1,93,No +727,hospital_1,Lev,46,Male,1139.2,Yes,No,No,Moderate,Serosa,Good,3,0,1918,Yes +728,hospital_4,Lev,60,Male,1134.4,No,No,No,Well,Muscle,Good,1,1,1932,Yes +729,hospital_1,Obs,60,Female,1134.4,No,No,No,Moderate,Muscle,Good,1,0,2278,No +730,hospital_5,Obs,57,Male,1132.8,Yes,No,No,Poor,Serosa,Bad,9,1,145,Yes +731,hospital_1,Lev,42,Female,1129.6,No,No,No,Poor,Serosa,Good,1,0,1913,Yes +732,hospital_2,Obs,58,Male,1113.6,No,No,No,Moderate,Serosa,Good,2,0,2176,Yes +733,hospital_3,Obs,53,Female,1108.8,No,No,No,Poor,Serosa,Good,1,0,1995,No +734,hospital_4,Lev,73,Male,1107.2,No,No,Yes,Moderate,Serosa,Good,1,0,2023,Yes +735,hospital_2,Obs,73,Male,1107.2,No,No,No,Moderate,Serosa,Good,7,0,1935,Yes +736,hospital_2,Obs,57,Male,1107.2,No,No,No,Moderate,Serosa,Good,NA,0,2191,No +737,hospital_2,Lev,77,Female,1099.2,No,No,No,Poor,Serosa,Good,1,0,2191,No +738,hospital_1,Obs,60,Male,1096,No,No,No,NA,Serosa,Good,2,0,1856,Yes +739,hospital_4,Lev,74,Male,1094.4,No,No,No,Moderate,Serosa,Bad,8,1,628,Yes +740,hospital_2,Lev,70,Male,1084.8,No,No,No,Moderate,Muscle,Good,3,0,1976,Yes +741,hospital_1,Obs,53,Female,1080,No,No,No,Moderate,Serosa,NA,5,0,1819,No +742,hospital_4,Lev,68,Female,1078.4,No,No,Yes,Moderate,Adjacent structures,Bad,8,1,141,Yes +743,hospital_4,Lev,59,Male,1076.8,Yes,No,No,Moderate,Serosa,Bad,2,1,422,Yes +744,hospital_3,Lev,29,Male,1072,Yes,No,No,Moderate,Serosa,Good,3,0,2006,Yes +745,hospital_1,Obs,57,Female,1070.4,No,No,No,Moderate,Muscle,Good,2,0,2113,Yes +746,hospital_3,Obs,61,Male,1065.6,No,No,No,Moderate,Muscle,NA,4,0,1823,Yes +747,hospital_2,Obs,68,Male,1064,Yes,No,No,Moderate,Serosa,Good,3,0,2170,Yes +748,hospital_3,Lev,49,Male,1062.4,No,No,No,Moderate,Serosa,Bad,11,1,1812,No +749,hospital_1,Lev,70,Female,1060.8,No,No,No,Moderate,Serosa,Good,2,0,1838,Yes +750,hospital_1,Obs,53,Male,1054.4,Yes,No,No,Moderate,Serosa,Good,2,0,1855,Yes +751,hospital_2,Lev,57,Female,1035.2,Yes,No,No,Poor,Serosa,Bad,2,1,269,No +752,hospital_2,Lev,76,Male,1028.8,No,No,No,Moderate,Serosa,Good,1,0,2414,Yes +753,hospital_2,Lev,59,Male,1028.8,No,No,Yes,Moderate,Muscle,Good,2,0,2174,Yes +754,hospital_3,Lev,56,Male,1027.2,No,No,No,Moderate,Muscle,Good,1,0,2263,No +755,hospital_4,Lev,38,Male,1027.2,No,No,No,Moderate,Serosa,Bad,7,1,1495,Yes +756,hospital_4,Lev,61,Female,1025.6,No,No,No,Poor,Serosa,Bad,10,1,314,Yes +757,hospital_3,Obs,49,Male,1006.4,No,No,No,Moderate,Serosa,Good,2,0,2261,Yes +758,hospital_5,Obs,69,Female,1004.8,No,No,No,Moderate,Serosa,Bad,12,1,716,Yes +759,hospital_3,Obs,53,Male,995.2,No,No,No,Moderate,Serosa,Good,1,0,2190,No +760,hospital_2,Lev,72,Female,985.6,No,No,No,Poor,Serosa,Good,6,0,2331,No +761,hospital_1,Lev,57,Female,982.4,No,No,No,Moderate,Serosa,Good,3,0,2187,Yes +762,hospital_5,Lev,73,Male,979.2,No,No,Yes,Moderate,Adjacent structures,Bad,1,1,602,Yes +763,hospital_4,Lev,58,Female,974.4,No,No,Yes,Well,Serosa,Bad,2,1,666,Yes +764,hospital_5,Lev,69,Male,972.8,No,No,No,Moderate,Serosa,Bad,5,1,138,Yes +765,hospital_1,Obs,69,Female,964.8,Yes,No,No,Poor,Serosa,Good,3,0,2001,Yes +766,hospital_5,Lev,47,Female,963.2,No,No,No,Moderate,Serosa,Bad,5,1,887,Yes +767,hospital_2,Lev,80,Female,963.2,No,Yes,No,Well,Muscle,Bad,2,1,1207,Yes +768,hospital_1,Lev,67,Male,961.6,No,No,No,Moderate,Serosa,Good,2,0,1997,Yes +769,hospital_1,Lev,54,Female,958.4,No,No,No,Moderate,Serosa,Good,1,0,1864,Yes +770,hospital_3,Lev,63,Male,952,NA,No,Yes,Poor,Serosa,Good,7,0,2422,No +771,hospital_4,Lev,65,Female,950.4,Yes,No,No,Poor,Serosa,Bad,NA,1,444,No +772,hospital_4,Lev,65,Female,947.2,No,Yes,Yes,Moderate,Serosa,Good,3,0,2375,Yes +773,hospital_5,Obs,48,Female,945.6,Yes,No,No,Moderate,Serosa,Bad,2,1,718,Yes +774,hospital_1,Obs,52,Male,942.4,No,No,No,Moderate,Serosa,Good,2,0,2204,Yes +775,hospital_1,Obs,67,Male,939.2,No,No,Yes,Well,Serosa,Good,1,0,2120,No +776,hospital_5,Lev,70,Female,932.8,No,Yes,Yes,Well,Serosa,Bad,5,1,766,Yes +777,hospital_5,Lev,51,Female,931.2,Yes,No,Yes,Poor,Serosa,Bad,6,1,366,Yes +778,hospital_5,Lev,32,Female,928,No,No,No,Poor,Muscle,Bad,14,1,1752,Yes +779,hospital_1,Lev,63,Male,928,No,No,Yes,Poor,Serosa,Good,7,0,2183,Yes +780,hospital_1,Obs,81,Female,924.8,No,No,Yes,Moderate,Serosa,Good,1,0,1902,Yes +781,hospital_3,Obs,66,Male,921.6,No,No,No,Moderate,Adjacent structures,Bad,7,1,259,No +782,hospital_4,Lev,60,Female,921.6,No,Yes,Yes,Poor,Serosa,Bad,4,1,609,Yes +783,hospital_5,Obs,81,Female,916.8,Yes,No,No,Well,Serosa,Bad,1,1,832,Yes +784,hospital_2,Obs,66,Male,912,Yes,No,Yes,Moderate,Serosa,Bad,4,1,164,No +785,hospital_2,Lev,78,Male,910.4,No,No,Yes,Poor,Serosa,Good,2,0,1828,No +786,hospital_2,Lev,46,Female,900.8,No,No,No,Moderate,Serosa,Good,3,0,2147,Yes +787,hospital_4,Obs,57,Female,900.8,No,No,No,Moderate,Serosa,Bad,NA,1,201,Yes +788,hospital_1,Lev,57,Female,894.4,No,No,No,Moderate,Submucosa,Good,3,0,2221,No +789,hospital_2,Lev,67,Female,884.8,No,No,No,Poor,Serosa,Bad,2,1,503,Yes +790,hospital_5,Lev,68,Male,880,No,No,No,Moderate,Serosa,Bad,9,1,376,Yes +791,hospital_2,Lev,38,Female,873.6,No,No,No,Moderate,Serosa,Bad,2,1,811,Yes +792,hospital_1,Lev,70,Female,859.2,No,No,No,Moderate,Serosa,Good,3,0,1985,Yes +793,hospital_1,Obs,66,Male,846.4,No,No,No,Moderate,Serosa,Good,2,0,2076,No +794,hospital_4,Lev,63,Male,844.8,No,No,No,Moderate,Serosa,Bad,8,1,1154,No +795,hospital_5,Lev,72,Male,835.2,No,No,No,Moderate,Muscle,Bad,5,1,844,No +796,hospital_2,Obs,61,Male,819.2,Yes,No,Yes,Well,Serosa,Bad,1,1,1031,No +797,hospital_5,Lev,46,Male,816,No,No,No,Moderate,Serosa,Bad,3,1,1302,No +798,hospital_2,Lev,36,Female,809.6,Yes,No,No,Moderate,Serosa,Good,3,0,2169,Yes +799,hospital_2,Obs,69,Female,804.8,No,No,No,Moderate,Muscle,Good,1,0,1929,Yes +800,hospital_2,Lev,75,Female,798.4,No,No,No,Moderate,Serosa,NA,1,0,1800,Yes +801,hospital_5,Lev,64,Female,798.4,No,No,No,Moderate,Serosa,Bad,12,1,355,No +802,hospital_1,Lev,77,Male,798.4,No,No,No,Moderate,Serosa,Bad,1,1,669,No +803,hospital_3,Obs,51,Female,796.8,NA,No,No,Moderate,Muscle,Bad,7,1,465,Yes +804,hospital_4,Obs,36,Male,784,No,No,No,Moderate,Serosa,Bad,6,0,2157,No +805,hospital_5,Obs,56,Male,777.6,No,No,No,Moderate,Serosa,Bad,7,1,929,Yes +806,hospital_3,Lev,63,Female,776,No,No,No,Moderate,Serosa,Good,2,0,2242,Yes +807,hospital_2,Lev,64,Male,774.4,No,No,No,Moderate,Serosa,Good,2,0,2212,Yes +808,hospital_1,Lev,44,Male,760,No,No,No,Moderate,Serosa,Good,1,0,2148,No +809,hospital_5,Lev,73,Male,758.4,Yes,No,No,Moderate,Serosa,Bad,7,1,171,Yes +810,hospital_3,Lev,54,Male,755.2,Yes,No,No,Moderate,Adjacent structures,Bad,1,1,629,Yes +811,hospital_2,Lev,44,Male,750.4,No,No,No,Moderate,Muscle,Good,2,1,1829,Yes +812,hospital_2,Lev,30,Male,744,No,Yes,No,Moderate,Serosa,Good,9,0,1939,No +813,hospital_5,Lev,65,Female,744,No,No,No,Moderate,Serosa,Bad,7,1,529,No +814,hospital_2,Obs,68,Female,742.4,Yes,No,No,Moderate,Serosa,Good,2,0,2130,Yes +815,hospital_1,Obs,56,Female,739.2,No,No,No,NA,Submucosa,Good,2,0,1990,Yes +816,hospital_3,Obs,62,Male,736,No,No,No,Poor,Serosa,Bad,5,1,587,Yes +817,hospital_4,Lev,36,Female,734.4,No,No,No,Well,Muscle,Bad,7,1,1145,Yes +818,hospital_1,Lev,57,Male,726.4,No,No,No,Well,Serosa,Good,2,0,2162,Yes +819,hospital_5,Lev,31,Male,724.8,Yes,No,No,Well,Serosa,Bad,NA,1,643,Yes +820,hospital_4,Lev,39,Male,716.8,No,No,No,Moderate,Serosa,Good,11,0,2129,No +821,hospital_5,Obs,53,Male,710.4,No,No,No,Moderate,Serosa,Bad,3,1,1437,Yes +822,hospital_5,Lev,60,Male,708.8,Yes,No,No,Moderate,Adjacent structures,Bad,14,1,512,Yes +823,hospital_1,Obs,65,Female,705.6,Yes,No,No,Moderate,Serosa,Good,1,0,2008,No +824,hospital_1,Lev,61,Female,702.4,No,No,No,Moderate,Serosa,NA,1,0,1814,Yes +825,hospital_4,Lev,77,Female,700.8,Yes,No,Yes,Moderate,Serosa,Good,3,0,2161,Yes +826,hospital_5,Obs,48,Female,700.8,Yes,No,No,Moderate,Serosa,Bad,5,1,506,No +827,hospital_2,Obs,77,Male,699.2,No,No,No,Well,Serosa,Bad,3,1,1482,Yes +828,hospital_3,Lev,69,Male,692.8,No,No,No,Poor,Serosa,Good,10,0,1964,Yes +829,hospital_5,Lev,36,Female,688,No,No,No,Poor,Serosa,Bad,17,1,693,Yes +830,hospital_3,Lev,64,Female,688,No,No,Yes,Moderate,Serosa,Bad,4,1,592,Yes +831,hospital_2,Lev,70,Male,684.8,No,No,No,Moderate,Muscle,Good,1,0,2207,Yes +832,hospital_1,Lev,74,Female,675.2,No,No,No,Well,Serosa,Good,3,0,2181,Yes +833,hospital_5,Lev,63,Male,673.6,No,No,No,Poor,Serosa,Bad,9,1,696,Yes +834,hospital_5,Lev,52,Female,672,No,No,No,Poor,Serosa,Bad,10,1,257,Yes +835,hospital_5,Lev,54,Female,667.2,No,No,No,Moderate,Serosa,Good,3,1,2171,Yes +836,hospital_4,Lev,54,Female,660.8,Yes,No,No,Moderate,Serosa,Good,4,0,2209,Yes +837,hospital_5,Lev,41,Female,660.8,Yes,No,No,Well,Serosa,Bad,1,1,1122,No +838,hospital_5,Obs,61,Female,657.6,No,No,No,Moderate,Serosa,Bad,4,1,936,Yes +839,hospital_5,Lev,34,Female,654.4,Yes,No,No,Poor,Serosa,Bad,10,1,601,Yes +840,hospital_1,Obs,59,Female,649.6,Yes,No,No,Moderate,Serosa,Good,3,0,2265,Yes +841,hospital_1,Lev,57,Female,643.2,No,No,No,Moderate,Serosa,Good,3,0,2198,Yes +842,hospital_5,Obs,39,Female,640,No,No,No,Moderate,Muscle,Bad,6,1,275,Yes +843,hospital_3,Obs,74,Male,624,No,No,No,Poor,Serosa,Bad,3,1,1195,Yes +844,hospital_4,Lev,45,Male,622.4,Yes,No,No,Moderate,Serosa,Good,3,0,2099,No +845,hospital_1,Lev,66,Female,614.4,No,No,No,Moderate,Serosa,Good,1,0,2165,Yes +846,hospital_4,Lev,60,Male,614.4,No,No,No,Moderate,Serosa,Good,2,0,2212,No +847,hospital_5,Lev,73,Male,611.2,No,No,No,Moderate,Serosa,Bad,1,1,355,No +848,hospital_1,Obs,76,Female,609.6,No,No,No,Poor,Muscle,Good,1,0,2097,Yes +849,hospital_2,Lev,79,Female,601.6,Yes,No,No,Moderate,Serosa,Bad,1,1,56,Yes +850,hospital_5,Lev,47,Male,595.2,Yes,No,No,Moderate,Serosa,Bad,4,1,589,No +851,hospital_5,Obs,60,Male,585.6,No,No,No,Moderate,Serosa,Bad,9,1,510,Yes +852,hospital_1,Lev,62,Female,584,No,No,No,Moderate,Serosa,Good,3,0,2250,No +853,hospital_5,Obs,18,Male,580.8,Yes,No,Yes,Poor,Muscle,Bad,4,1,612,No +854,hospital_4,Lev,75,Female,579.2,No,No,No,Moderate,Serosa,Good,5,0,2284,Yes +855,hospital_2,Lev,56,Female,569.6,No,No,No,Well,Serosa,Good,3,0,1992,No +856,hospital_4,Lev,70,Male,568,Yes,No,No,Moderate,Muscle,Bad,5,1,251,Yes +857,hospital_2,Lev,54,Female,568,No,No,No,NA,Muscle,Good,3,0,2070,Yes +858,hospital_5,Obs,64,Female,558.4,No,No,No,Moderate,Serosa,Bad,1,1,1209,No +859,hospital_3,Lev,63,Female,548.8,No,No,No,Moderate,Serosa,Good,1,0,2122,Yes +860,hospital_3,Lev,52,Female,547.2,Yes,No,No,Well,Serosa,Good,2,0,2111,No +861,hospital_5,Lev,71,Female,544,No,No,Yes,Moderate,Serosa,Bad,11,1,274,No +862,hospital_3,Lev,54,Female,529.6,No,No,No,Well,Serosa,Bad,1,1,1306,No +863,hospital_3,Lev,27,Female,521.6,No,No,No,Poor,Muscle,Bad,1,1,1325,Yes +864,hospital_2,Obs,68,Male,518.4,No,No,Yes,Moderate,Serosa,Good,10,0,1968,Yes +865,hospital_4,Obs,49,Female,516.8,No,No,No,Moderate,Serosa,Bad,2,1,753,No +866,hospital_4,Obs,61,Male,515.2,No,No,Yes,Moderate,Adjacent structures,Bad,2,1,760,Yes +867,hospital_2,Lev,40,Male,505.6,No,No,No,Moderate,Serosa,Good,16,0,1861,Yes +868,hospital_5,Lev,38,Male,502.4,No,No,No,Well,Serosa,Bad,3,1,1138,Yes +869,hospital_1,Obs,56,Female,502.4,No,No,No,Moderate,Muscle,Good,2,0,2167,Yes +870,hospital_4,Lev,79,Male,500.8,Yes,No,No,Moderate,Serosa,Good,1,0,1944,Yes +871,hospital_4,Obs,55,Female,497.6,No,No,No,Poor,Serosa,Bad,13,1,372,No +872,hospital_4,Obs,59,Female,486.4,No,No,No,Moderate,Submucosa,NA,1,0,1792,No +873,hospital_5,Lev,36,Male,483.2,No,No,Yes,Moderate,Serosa,Bad,4,1,986,Yes +874,hospital_4,Lev,63,Female,468.8,Yes,No,No,Moderate,Serosa,Good,2,0,2378,Yes +875,hospital_5,Obs,27,Male,462.4,No,Yes,Yes,Moderate,Serosa,Bad,12,1,390,Yes +876,hospital_5,Lev,66,Female,452.8,No,No,Yes,Moderate,Muscle,Bad,2,1,642,Yes +877,hospital_3,Lev,63,Male,452.8,No,No,No,Moderate,Serosa,Good,3,0,2345,Yes +878,hospital_4,Lev,64,Male,446.4,No,No,No,Moderate,Muscle,Good,2,0,2254,No +879,hospital_1,Obs,78,Female,441.6,No,No,No,Moderate,Serosa,Good,1,0,2118,Yes +880,hospital_5,Lev,66,Female,440,Yes,No,No,Moderate,Serosa,Good,2,1,1831,Yes +881,hospital_2,Obs,64,Female,438.4,No,No,No,Poor,Serosa,Good,3,0,2167,Yes +882,hospital_4,Obs,68,Male,433.6,No,No,No,Moderate,Serosa,Bad,2,1,1198,Yes +883,hospital_2,Lev,35,Male,430.4,No,No,Yes,Moderate,Serosa,Good,2,0,2050,No +884,hospital_4,Lev,64,Male,422.4,No,No,Yes,Poor,Serosa,Bad,2,1,271,Yes +885,hospital_1,Lev,60,Female,414.4,No,No,No,Moderate,Muscle,Good,2,0,2138,Yes +886,hospital_3,Obs,55,Female,414.4,Yes,No,No,Moderate,Serosa,Good,1,0,1891,Yes +887,hospital_5,Obs,39,Male,411.2,No,No,No,Moderate,Serosa,Bad,6,1,1313,Yes +888,hospital_3,Lev,67,Male,404.8,No,No,No,Moderate,Serosa,Good,3,0,1853,Yes +889,hospital_1,Lev,55,Male,401.6,Yes,No,No,Poor,Serosa,Good,3,0,2130,Yes +890,hospital_5,Lev,61,Male,387.2,No,No,No,Moderate,Serosa,Bad,8,1,150,No +891,hospital_5,Lev,67,Female,385.6,No,No,No,Moderate,Serosa,Bad,6,1,759,Yes +892,hospital_3,Lev,62,Male,380.8,No,No,No,Moderate,Serosa,Good,1,0,2100,Yes +893,hospital_1,Lev,52,Female,371.2,No,No,No,Moderate,Serosa,Good,4,0,2101,Yes +894,hospital_5,Lev,80,Male,361.6,No,No,No,Moderate,Serosa,Bad,1,1,942,Yes +895,hospital_4,Obs,51,Female,355.2,No,No,No,Moderate,Serosa,NA,11,0,1823,Yes +896,hospital_5,Obs,74,Male,350.4,No,No,No,Poor,Submucosa,Bad,1,1,665,No +897,hospital_5,Obs,70,Male,350.4,Yes,Yes,Yes,Moderate,Serosa,Bad,4,1,1656,Yes +898,hospital_1,Lev,73,Male,348.8,No,No,No,Moderate,Serosa,Good,4,0,1969,Yes +899,hospital_3,Lev,56,Female,344,No,No,No,Poor,Adjacent structures,Good,3,0,2190,No +900,hospital_5,Obs,70,Female,332.8,Yes,No,No,Moderate,Serosa,Bad,15,1,576,Yes +901,hospital_5,Lev,68,Male,329.6,No,No,No,Moderate,Serosa,Bad,12,1,1103,Yes +902,hospital_5,Lev,51,Male,321.6,No,No,Yes,Poor,Serosa,Bad,2,1,1046,Yes +903,hospital_1,Lev,56,Female,305.6,No,No,No,Moderate,Serosa,Good,3,0,1929,Yes +904,hospital_5,Obs,71,Male,299.2,No,No,No,Well,Serosa,Bad,10,1,125,Yes +905,hospital_2,Obs,63,Female,297.6,No,No,No,Well,Serosa,Bad,2,1,187,Yes +906,hospital_2,Lev,82,Male,273.6,NA,No,No,Moderate,Serosa,Bad,3,1,939,Yes +907,hospital_4,Obs,68,Female,273.6,No,No,No,Poor,Serosa,Bad,12,1,887,No +908,hospital_2,Obs,55,Female,265.6,No,No,No,Moderate,Serosa,NA,2,0,1803,No +909,hospital_1,Lev,71,Male,264,No,No,No,Moderate,Serosa,Good,1,0,2018,Yes +910,hospital_5,Lev,68,Female,262.4,No,No,Yes,Moderate,Serosa,Bad,12,1,1509,Yes +911,hospital_5,Lev,60,Male,240,No,No,No,Moderate,Serosa,Bad,13,1,314,No +912,hospital_1,Lev,72,Male,232,No,No,No,Well,Serosa,Good,3,0,1971,Yes +913,hospital_2,Lev,69,Male,230.4,Yes,Yes,Yes,Moderate,Serosa,Good,3,0,1827,Yes +914,hospital_5,Obs,46,Female,225.6,Yes,No,No,Moderate,Muscle,Bad,3,1,1079,No +915,hospital_4,Lev,42,Female,220.8,No,No,No,Well,Serosa,Good,6,0,2114,Yes +916,hospital_5,Obs,37,Female,212.8,No,No,No,Moderate,Serosa,Bad,8,1,1262,Yes +917,hospital_4,Obs,71,Female,206.4,No,No,No,Poor,Serosa,Bad,5,1,259,Yes +918,hospital_3,Lev,50,Male,203.2,No,No,No,Moderate,Muscle,Bad,7,1,323,No +919,hospital_5,Lev,70,Female,200,Yes,No,Yes,Moderate,Muscle,Bad,1,1,678,Yes +920,hospital_4,Lev,70,Female,195.2,No,No,Yes,Moderate,Muscle,Good,5,0,1827,Yes +921,hospital_5,Lev,58,Male,180.8,Yes,No,No,Moderate,Adjacent structures,Bad,3,1,1399,No +922,hospital_4,Lev,70,Female,148.8,No,No,No,Moderate,Serosa,Bad,1,1,1022,Yes +923,hospital_4,Lev,55,Male,126.4,Yes,No,No,Poor,Serosa,Good,2,0,2240,Yes +924,hospital_1,Obs,64,Male,89.6,Yes,No,Yes,Poor,Serosa,Good,2,0,2158,Yes +925,hospital_4,Lev,71,Male,83.2,No,No,Yes,Moderate,Serosa,Good,4,0,1875,Yes +926,hospital_2,Lev,72,Female,72,No,No,No,Moderate,Serosa,Good,1,0,2154,Yes +927,hospital_2,Lev,76,Male,54.4,No,No,Yes,Poor,Serosa,Bad,1,1,1018,Yes +928,hospital_2,Lev,48,Female,38.4,Yes,No,No,Moderate,Serosa,Good,4,0,2072,No +929,hospital_2,Lev,66,Female,36.8,Yes,No,No,Moderate,Serosa,NA,1,0,1820,Yes diff --git a/data/cancer.xlsx b/data/cancer.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4680846ad2e6891c7436871e37e40a64d7cec393 Binary files /dev/null and b/data/cancer.xlsx differ diff --git a/radiant-master/DESCRIPTION b/radiant-master/DESCRIPTION index d4f05fe4133dd3e0be1b4d5b4ce79d106e17e47b..beb0420b5140be589f76885da7cabbc03719d4e6 100644 --- a/radiant-master/DESCRIPTION +++ b/radiant-master/DESCRIPTION @@ -14,7 +14,8 @@ Depends: radiant.design (>= 1.6.6), radiant.basics (>= 1.6.6), radiant.model (>= 1.6.6), - radiant.multivariate (>= 1.6.6) + radiant.multivariate (>= 1.6.6), + radiant.quickgen Imports: shiny (>= 1.8.1), import (>= 1.1.0), diff --git a/radiant-master/inst/app/global.R b/radiant-master/inst/app/global.R index 58acd78b6e134b0f66c72de57f5ab87d71e97881..1a1e7b7e3d4c90b4930c5ca5342abf0ede9830ee 100644 --- a/radiant-master/inst/app/global.R +++ b/radiant-master/inst/app/global.R @@ -42,7 +42,6 @@ source(file.path(getOption("radiant.path.design"), "app/init.R"), encoding = get source(file.path(getOption("radiant.path.basics"), "app/init.R"), encoding = getOption("radiant.encoding"), local = TRUE) source(file.path(getOption("radiant.path.model"), "app/init.R"), encoding = getOption("radiant.encoding"), local = TRUE) source(file.path(getOption("radiant.path.multivariate"), "app/init.R"), encoding = getOption("radiant.encoding"), local = TRUE) -# 添加quickgen模块的init.R source(file.path(getOption("radiant.path.quickgen"), "app/init.R"), encoding = getOption("radiant.encoding"), local = TRUE) options(radiant.url.patterns = make_url_patterns()) diff --git a/radiant-master/inst/translations/translation_zh.csv b/radiant-master/inst/translations/translation_zh.csv index d59a979b9b6270d6213059c18f481d9ac91f7169..f4877061a8d59c6965068c215c9e19d19d1e1146 100644 --- a/radiant-master/inst/translations/translation_zh.csv +++ b/radiant-master/inst/translations/translation_zh.csv @@ -20,7 +20,7 @@ Sample size:,样本大小:,"clt_ui.R,sampling_ui.R" # of samples:,样本数量:,clt_ui.R Number of bins:,分箱数量:,"clt_ui.R,visualize_ui.R" Central Limit Theorem,中心极限定理,"clt_ui.R,init.R" -Basics > Probability,基础 > 概率,clt_ui.R +Basics > Probability,基础统计 > 概率,clt_ui.R Please choose a sample size larger than 2,请选择一个大于 2 的样本大小,clt_ui.R Please choose 2 or more samples,请选择 2 个或更多样本,clt_ui.R Please choose a minimum value for the uniform distribution,请为均匀分布选择一个最小值,clt_ui.R @@ -61,9 +61,9 @@ Wilcox,Wilcoxon 检验,compare_means_ui.R Select plots:,选择绘图类型:,compare_means_ui.R Select plots,选择绘图,compare_means_ui.R Compare means,均值比较,"compare_means_ui.R,init.R" -Summary,摘要,"compare_means_ui.R,doe_ui.R, randomizer_ui.R, sample_size_comp.R, sample_size_ui.R, sampling_ui.R,gbt_ui.R,conjoint_ui.R" -Plot,图形,"compare_means_ui.R,sample_size_comp.R,dtree_ui.R, gbt_ui.R,conjoint_ui.R" -Basics > Means,基础 > 均值,compare_means_ui.R +Summary,摘要,"compare_means_ui.R,doe_ui.R, randomizer_ui.R, sample_size_comp.R, sample_size_ui.R, sampling_ui.R,gbt_ui.R,conjoint_ui.R,crtree_ui.R,crs_ui.R" +Plot,图形,"compare_means_ui.R,sample_size_comp.R,dtree_ui.R, gbt_ui.R,conjoint_ui.R,crtree_ui.R,crs_ui.R" +Basics > Means,基础统计 > 均值,compare_means_ui.R "This analysis requires at least two variables. The first can be of type factor, numeric, or interval. The second must be of type numeric or interval. If these variable types are not available please select another dataset. @@ -72,7 +72,7 @@ If these variable types are not available please select another dataset. ",compare_means_ui.R Nothing to plot. Please select a plot type,没有可绘制的内容,请选择绘图类型,compare_means_ui.R Save compare means plot,保存均值比较图,compare_means_ui.R -Basics > Proportions,基础 > 比例,compare_props_ui.R +Basics > Proportions,基础统计 > 比例,compare_props_ui.R Compare proportions,比较比例,"compare_props_ui.R,init.R" "This analysis requires two categorical variables. The first must have two or more levels. The second can have only two levels. If these @@ -88,7 +88,7 @@ Pearson,皮尔逊积矩相关,correlation_ui.R Spearman,斯皮尔曼秩相关,correlation_ui.R Kendall,肯德尔秩相关,correlation_ui.R Calculate correlation,计算相关性,correlation_ui.R -Basics > Tables,基础 > 表格,correlation_ui.R +Basics > Tables,基础统计 > 表格,correlation_ui.R Correlation,相关性,"correlation_ui.R,init.R" Adjust for {factor} variables,针对 {factor} 变量进行调整,"correlation_ui.R,full_factor_ui.R" Calculate adjusted p.values,计算调整后的 p 值,correlation_ui.R @@ -252,7 +252,7 @@ Load data,加载数据,manage_ui.R Description,描述,manage_ui.R Paste,粘贴,manage_ui.R Copy data,复制数据,manage_ui.R -Save,保存,"manage_ui.R,logistic_ui.R,radiant.R" +Save,保存,"manage_ui.R,logistic_ui.R,radiant.R,quickgen_ai_ui.R" Save data,保存数据,manage_ui.R Save radiant state file,保存 Radiant 状态文件,"manage_ui.R,global.R" Add/edit data description,添加/编辑数据描述,manage_ui.R @@ -608,7 +608,7 @@ Estimate model,估计模型,"crs_ui.R, crtree_ui.R, gbt_ui.R, logistic_ui.R,conj Re-estimate model,重新估计模型,"crs_ui.R, crtree_ui.R, gbt_ui.R, logistic_ui.R,conjoint_ui.R" ,,crs_ui.R Collaborative Filtering,协同过滤,"crs_ui.R,init.R" -Model > Recommend,模型 > 推荐,crs_ui.R +Model > Recommend,模型方法 > 推荐,crs_ui.R "This analysis requires a user id, a product id, and product ratings. If these variables are not available please select another dataset. @@ -675,7 +675,7 @@ Save decision tree plot,保存决策树图,crtree_ui.R Generating predictions,正在生成预测,"crtree_ui.R, gbt_ui.R, logistic_ui.R,conjoint_ui.R" Generating prediction plot,正在生成预测图,"crtree_ui.R, gbt_ui.R, logistic_ui.R,conjoint_ui.R" Generating tree diagramm,正在生成树图,crtree_ui.R -Model > Estimate,模型 > 估计,"crtree_ui.R, logistic_ui.R" +Model > Estimate,模型方法 > 估计,"crtree_ui.R, logistic_ui.R" ** Press the Estimate button to estimate the model **,** 点击“估计模型”按钮来估计模型 **,"crtree_ui.R, gbt_ui.R,conjoint_ui.R" Please select one or more explanatory variables.,请选择一个或多个自变量。,"crtree_ui.R, gbt_ui.R, nn_ui.R" Max,最大化,dtree_ui.R @@ -689,7 +689,7 @@ Select decisions to evaluate,选择要评估的决策,dtree_ui.R ","",dtree_ui.R Step:,步长:,dtree_ui.R -Model,模型,"dtree_ui.R,init.R" +Model,模型方法,"dtree_ui.R,init.R" Decision analysis,决策分析,"dtree_ui.R,init.R" ,,dtree_ui.R ,,dtree_ui.R @@ -757,7 +757,7 @@ Save model evaluation plot,保存模型评估图,"evalbin_ui.R, evalreg_ui.R" Save confusion plots,保存混淆图,evalbin_ui.R Save uplift plots,保存提升图,evalbin_ui.R Evaluate,评估,"evalbin_ui.R,init.R" -Model > Evaluate,模型 > 评估,"evalbin_ui.R, evalreg_ui.R" +Model > Evaluate,模型方法 > 评估,"evalbin_ui.R, evalreg_ui.R" ** Press the Evaluate button to evaluate models **,** 请点击“评估”按钮以评估模型 **,"evalbin_ui.R, evalreg_ui.R" ,,evalbin_ui.R "This analysis requires a response variable of type factor and one or more @@ -784,7 +784,7 @@ Sub-sample:,子样本比例:,gbt_ui.R # rounds:,迭代轮数:,gbt_ui.R Early stopping:,提前停止:,gbt_ui.R Gradient Boosted Trees,梯度提升树,"gbt_ui.R,init.R" -Model > Trees,模型 > 树模型,gbt_ui.R +Model > Trees,模型方法 > 树模型,gbt_ui.R ** Select prediction input **,** 请选择预测输入 **,"gbt_ui.R, logistic_ui.R,conjoint_ui.R" ** Select data for prediction **,** 请选择用于预测的数据 **,"gbt_ui.R, logistic_ui.R,conjoint_ui.R" ** Enter prediction commands **,** 请输入预测命令 **,"gbt_ui.R, logistic_ui.R,conjoint_ui.R" @@ -796,7 +796,7 @@ Save gradient boosted trees prediction plot,保存梯度提升树预测图,gbt_u Save gradient boosted trees plot,保存梯度提升树图,gbt_ui.R This analysis requires a response variable with two levels and one\nor more explanatory variables. If these variables are not available\nplease select another dataset.\n\n,此分析需要一个具有两个水平的响应变量和一个\n或多个解释变量。如果这些变量不可用\n请选择其他数据集。\n\n,gbt_ui.R This analysis requires a response variable of type integer\nor numeric and one or more explanatory variables.\nIf these variables are not available please select another dataset.\n\n,此分析需要一个整数类型的响应变量\n或数值型,以及一个或多个解释变量。\n如果这些变量不可用,请选择其他数据集。\n\n,gbt_ui.R -Predict,预测,"gbt_ui.R,conjoint_ui.R" +Predict,预测,"gbt_ui.R,conjoint_ui.R,crtree_ui.R" Storing residuals,存储残差,logistic_ui.R Save coefficients,保存系数,logistic_ui.R Save logistic prediction plot,保存逻辑回归预测图,logistic_ui.R @@ -1090,7 +1090,7 @@ Radiant docs,Radiant文档,global.R Report issue,报告问题,global.R Design,设计,init.R Sample,样本,init.R -Basics,基础,init.R +Basics,基础统计,init.R Probability,概率,init.R Means,均值,init.R Proportions,比例,init.R @@ -1127,12 +1127,12 @@ Base dir:,根目录:,global.R Generate descriptive statistics with one click,一键生成描述性统计,"quickgen_basic_ui.R,init.R" Oneclick generation > Generate descriptive statistics,一键生成 > 生成描述性统计,quickgen_basic_ui.R Oneclick generation,一键生成,init.R -LLM generates descriptive statistics,大模型生成描述性统计,init.R +AI generates descriptive statistics,大模型生成描述性统计,"init.R,quickgen_ai_ui.R" Select All,全选,quickgen_basic_ui.R Deselect All,全不选,quickgen_basic_ui.R Invert,反选,quickgen_basic_ui.R Radiant screenshot,截图,radiant.R -Cancel,取消,radiant.R +Cancel,取消,"radiant.R,quickgen_ai_ui.R" Table,表格,quickgen_basic_ui.R OneClick table generation,一键成表,quickgen_basic_ui.R Select numeric variables,选择数值变量,quickgen_basic_ui.R @@ -1143,3 +1143,46 @@ Select X variable(s),选择X变量,quickgen_basic_ui.R No data available,暂无数据,quickgen_basic_ui.R No numerical variable available,无可用数值变量,quickgen_basic_ui.R ### Current data overview,### 当前数据概况,quickgen_basic_ui.R +Describe your analysis request:,描述您的分析请求:,quickgen_ai_ui.R +Oneclick generation > AI generates descriptive statistics,一键生成 > 大模型生成描述性统计,quickgen_ai_ui.R +AI assistant,AI助手,quickgen_ai_ui.R +Run code,运行,quickgen_ai_ui.R +Edit code,编辑,quickgen_ai_ui.R +Generated R code,生成的R代码,quickgen_ai_ui.R +Send,发送,quickgen_ai_ui.R +e. g. Please help me draw a scatter plot of diamonds prices and carats,e.g. 请帮我画一张 diamonds 价格与克拉的散点图,quickgen_ai_ui.R +Please enter an analysis request,请输入分析请求,quickgen_ai_ui.R +Save Changes,保存,quickgen_ai_ui.R +Edit R Code,编辑R代码,quickgen_ai_ui.R +Save AI-generated plot,保存大模型生成的图表,quickgen_ai_ui.R +Edit the generated R code here...,在此处编辑生成的R代码...,quickgen_ai_ui.R +Normality test,正态性检验,init.R +Homogeneity of variance test,方差齐性检验,init.R +Basics > Normality,基础统计 > 正态性,normality_test_ui.R +Shapiro-Wilk,SW 检验,normality_test_ui.R +Kolmogorov-Smirnov,K-S 检验,normality_test_ui.R +Anderson-Darling,AD 检验,normality_test_ui.R +Basics > Homogeneity,基础统计 > 方差齐性,homo_variance_test_ui.R +Grouping variable:,分组变量:,homo_variance_test_ui.R +Test method:,检验方法:,homo_variance_test_ui.R +Levene,莱文检验,homo_variance_test_ui.R +Bartlett,巴特利特检验,homo_variance_test_ui.R +Fligner,弗林格检验,homo_variance_test_ui.R +Cox Proportional Hazards Regression,比例风险回归,init.R +Support Vector Machine (SVM),支持向量机(SVM),init.R +Kernel:,核函数:,svm_ui.R +Linear,线性,svm_ui.R +Polynomial,多项式,svm_ui.R +Radial,径向基,svm_ui.R +Cost (C):,惩罚系数 (C):,svm_ui.R +Gamma:,伽马系数:,svm_ui.R +Coef0:,常数项:,svm_ui.R +Epsilon (tube):,Epsilon 间隔带:,svm_ui.R +Estimate class probabilities,估计类别概率,svm_ui.R +Choose Excel file:,选择Excel文件:,manage_ui.R +Sheet index (1-based):,工作表索引(从1开始):,manage_ui.R +First row as header,第一行为表头,manage_ui.R +Time variable:,生存时间变量:,cox_ui.R +Status variable:,事件状态变量:,cox_ui.R +AI running...,大模型运行中...,quickgen_ai_ui.R +Warning:Please enter a request related to descriptive statistics or visualization.,警告:请输入与描述性统计或可视化相关的请求。,quickgen_ai_ui.R diff --git a/radiant.quickgen/DESCRIPTION b/radiant.quickgen/DESCRIPTION index 9f58e63a931a8b8c7fa2c153e798f22812405802..425bf4ce2cb9c21c963b0408f794e6fae8993b6e 100644 --- a/radiant.quickgen/DESCRIPTION +++ b/radiant.quickgen/DESCRIPTION @@ -2,3 +2,21 @@ Package: radiant.quickgen Version: 0.0.1 Title: Quick Generator table and chart for Radiant Description: Provides a simple data generator for the Radiant interface. +Depends: + R (>= 4.3.0), + radiant.data (>= 1.6.6) +Imports: + shiny (>= 1.8.1), + shiny.i18n, + httr2 (>= 1.0.0), + shinyjs, + shinyAce, + shinyWidgets(>= 0.8.0), + patchwork +Suggests: + testthat (>= 2.0.0), + pkgdown (>= 1.1.0), + markdown (>= 1.3) +Encoding: UTF-8 +Language: en-US +RoxygenNote: 7.3.2 diff --git a/radiant.quickgen/NAMESPACE b/radiant.quickgen/NAMESPACE new file mode 100644 index 0000000000000000000000000000000000000000..907d6115bd4764254075ad795afa118c89879532 --- /dev/null +++ b/radiant.quickgen/NAMESPACE @@ -0,0 +1,40 @@ +# Generated by roxygen2: do not edit by hand + +S3method(dtab,explore) +S3method(store,explore) +S3method(summary,explore) +export(ai_generate) +export(ai_get_data_call) +export(ai_run_code) +export(build_r_prompt) +export(chat_completion) +export(cv) +export(does_vary) +export(empty_level) +export(explore) +export(flip) +export(ln) +export(me) +export(meprop) +export(modal) +export(n_missing) +export(n_obs) +export(p01) +export(p025) +export(p05) +export(p10) +export(p25) +export(p75) +export(p90) +export(p95) +export(p975) +export(p99) +export(prop) +export(qscatter) +export(sdpop) +export(sdprop) +export(se) +export(seprop) +export(varpop) +export(varprop) +export(visualize) diff --git a/radiant.quickgen/R/quickgen_ai.R b/radiant.quickgen/R/quickgen_ai.R index 696fd7d684532af846334f854e1770ef2113292c..7107e9aec41ed4b30f7292b5af735ce6bed82cfa 100644 --- a/radiant.quickgen/R/quickgen_ai.R +++ b/radiant.quickgen/R/quickgen_ai.R @@ -1,9 +1,98 @@ -#' 一键生成模块服务器逻辑 +# === 配置 === +MODELSCOPE_OPENAI_URL <- "https://api-inference.modelscope.cn/v1" +MODELSCOPE_API_KEY <- Sys.getenv("MODELSCOPE_API_KEY", "ms-b2746d72-f897-4faf-8089-89e5e511ed5a") +MODEL_ID <- "deepseek-ai/DeepSeek-V3.1" + +# === 低层封装:单次对话 === #' @export -quickgen_server <- function(input, output, session, r_data, r_info, r_state) { - # 为模块创建命名空间 - ns <- session$ns +chat_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) + body <- httr2::resp_body_json(resp) + + if (is.null(body$choices[[1]]$message$content)) + stop("ModelScope API 返回空内容:", body) + + body$choices[[1]]$message$content +} + +# === 构造发给模型的 Prompt === +#' @export +build_r_prompt <- function(user_prompt, data_call) { + sprintf( + "你是 R 语言专家,必须严格遵守以下规则: + +〓 输出格式 〓 +- 只返回可运行 R 代码,用 ```r 包裹,禁止任何解释、注释、空行。 +- 若用户请求不符合下方【白名单】,一律返回空代码块(仅 ```r\n``` ),不对话。 + +〓 白名单关键词(必须至少出现 1 个)〓 +箱线图|柱状图|条形图|散点图|折线图|密度图|直方图|热图|森林图|瀑布图|饼图|气泡图|生存曲线|KM 曲线|ggsurvplot|tbl_summary|tableone|CreateTableOne|描述性统计|基线表|相关性|group comparison|distribution|ggplot|geom_|patchwork + +〓 否定示例(立即返回空块)〓 +- 仅输入:“图表”“表格”“画图”“来张图” +- 非医学/统计描述:笑话、故事、计算、翻译、写文章、写代码注释、解释概念、生成非 ggplot 图形(base、lattice) + +〓 技术细节 〓 +1. 数据集已读入:%s +2. 主题函数带括号:theme_minimal()、theme_bw() ... +3. 多张图用 patchwork 拼页。 +4. 包函数写全名,不得省略括号。 + +用户请求:%s", + data_call, user_prompt + ) +} + +#' @export +ai_generate <- function(prompt, dataset, envir = parent.frame()) { + data_call <- ai_get_data_call(dataset, envir) + sys_prompt <- build_r_prompt(prompt, data_call) + r_code <- try(chat_completion(sys_prompt), silent = TRUE) + if (inherits(r_code, "try-error")) + stop("AI 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 <- 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_tbl <- grepl("data\\.frame\\(|tibble\\(|tbl_summary|tableOne|CreateTableOne", 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 +ai_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 +ai_run_code <- function(r_code, envir = parent.frame()) { + eval(parse(text = r_code), envir = envir) } \ No newline at end of file diff --git a/radiant.quickgen/R/quickgen_basic.R b/radiant.quickgen/R/quickgen_basic.R index 02da8b09f2838cdf53538c41bf7bca7eccdf6f1c..da304f79797ebfc7a2ae11781b59bd9124df562a 100644 --- a/radiant.quickgen/R/quickgen_basic.R +++ b/radiant.quickgen/R/quickgen_basic.R @@ -1,4 +1,4 @@ - +#' @export explore <- function(dataset, vars = "", byvar = "", fun = c("mean", "sd"), top = "fun", tabfilt = "", tabsort = "", tabslice = "", nr = Inf, data_filter = "", arr = "", rows = NULL, @@ -171,7 +171,7 @@ explore <- function(dataset, vars = "", byvar = "", fun = c("mean", "sd"), ) %>% add_class("explore") } - +#' @export summary.explore <- function(object, dec = 3, ...) { cat("Explore\n") cat("Data :", object$df_name, "\n") @@ -209,7 +209,7 @@ summary.explore <- function(object, dec = 3, ...) { invisible() } - +#' @export store.explore <- function(dataset, object, name, ...) { if (missing(name)) { object$tab @@ -225,7 +225,7 @@ store.explore <- function(dataset, object, name, ...) { } } - +#' @export flip <- function(expl, top = "fun") { cvars <- expl$byvar %>% (function(x) if (is.empty(x[1])) character(0) else x) @@ -245,7 +245,7 @@ flip <- function(expl, top = "fun") { expl$tab } - +#' @export dtab.explore <- function(object, dec = 3, searchCols = NULL, order = NULL, pageLength = NULL, caption = NULL, ...) { @@ -330,31 +330,31 @@ dtab.explore <- function(object, dec = 3, searchCols = NULL, ## turn functions below into functional ... ########################################### - +#' @export n_obs <- function(x, ...) length(x) - +#' @export n_missing <- function(x, ...) sum(is.na(x)) - +#' @export p01 <- function(x, na.rm = TRUE) quantile(x, .01, na.rm = na.rm) - +#' @export p025 <- function(x, na.rm = TRUE) quantile(x, .025, na.rm = na.rm) - +#' @export p05 <- function(x, na.rm = TRUE) quantile(x, .05, na.rm = na.rm) - +#' @export p10 <- function(x, na.rm = TRUE) quantile(x, .1, na.rm = na.rm) - +#' @export p25 <- function(x, na.rm = TRUE) quantile(x, .25, na.rm = na.rm) - +#' @export p75 <- function(x, na.rm = TRUE) quantile(x, .75, na.rm = na.rm) - +#' @export p90 <- function(x, na.rm = TRUE) quantile(x, .90, na.rm = na.rm) - +#' @export p95 <- function(x, na.rm = TRUE) quantile(x, .95, na.rm = na.rm) - +#' @export p975 <- function(x, na.rm = TRUE) quantile(x, .975, na.rm = na.rm) - +#' @export p99 <- function(x, na.rm = TRUE) quantile(x, .99, na.rm = na.rm) - +#' @export cv <- function(x, na.rm = TRUE) { m <- mean(x, na.rm = na.rm) if (m == 0) { @@ -364,17 +364,17 @@ cv <- function(x, na.rm = TRUE) { sd(x, na.rm = na.rm) / m } } - +#' @export se <- function(x, na.rm = TRUE) { if (na.rm) x <- na.omit(x) sd(x) / sqrt(length(x)) } - +#' @export me <- function(x, conf_lev = 0.95, na.rm = TRUE) { if (na.rm) x <- na.omit(x) se(x) * qt(conf_lev / 2 + .5, length(x) - 1, lower.tail = TRUE) } - +#' @export prop <- function(x, na.rm = TRUE) { if (na.rm) x <- na.omit(x) if (is.numeric(x)) { @@ -387,36 +387,36 @@ prop <- function(x, na.rm = TRUE) { NA } } - +#' @export varprop <- function(x, na.rm = TRUE) { p <- prop(x, na.rm = na.rm) p * (1 - p) } - +#' @export sdprop <- function(x, na.rm = TRUE) sqrt(varprop(x, na.rm = na.rm)) - +#' @export seprop <- function(x, na.rm = TRUE) { if (na.rm) x <- na.omit(x) sqrt(varprop(x, na.rm = FALSE) / length(x)) } - +#' @export meprop <- function(x, conf_lev = 0.95, na.rm = TRUE) { if (na.rm) x <- na.omit(x) seprop(x) * qnorm(conf_lev / 2 + .5, lower.tail = TRUE) } - +#' @export varpop <- function(x, na.rm = TRUE) { if (na.rm) x <- na.omit(x) n <- length(x) var(x) * ((n - 1) / n) } - +#' @export sdpop <- function(x, na.rm = TRUE) sqrt(varpop(x, na.rm = na.rm)) - +#' @export ln <- function(x, na.rm = TRUE) { if (na.rm) log(na.omit(x)) else log(x) } - +#' @export does_vary <- function(x, na.rm = TRUE) { ## based on http://stackoverflow.com/questions/4752275/test-for-equality-among-all-elements-of-a-single-vector if (length(x) == 1L) { @@ -429,7 +429,7 @@ does_vary <- function(x, na.rm = TRUE) { } } } - +#' @export empty_level <- function(x) { if (!is.factor(x)) x <- as.factor(x) levs <- levels(x) @@ -443,7 +443,7 @@ empty_level <- function(x) { } x } - +#' @export modal <- function(x, na.rm = TRUE) { if (na.rm) x <- na.omit(x) unv <- unique(x) @@ -451,7 +451,7 @@ modal <- function(x, na.rm = TRUE) { } #—————————————————————————————————————————————————绘图部分——————————————————————————————————————————— - +#' @export visualize <- function(dataset, xvar, yvar = "", comby = FALSE, combx = FALSE, type = ifelse(is.empty(yvar), "dist", "scatter"), nrobs = -1, facet_row = ".", facet_col = ".", color = "none", fill = "none", @@ -1131,7 +1131,7 @@ visualize <- function(dataset, xvar, yvar = "", comby = FALSE, combx = FALSE, (function(x) if (isTRUE(shiny)) x else print(x)) } } - +#' @export qscatter <- function(dataset, xvar, yvar, lev = "", fun = "mean", bins = 20) { if (is.character(dataset[[yvar]])) { dataset <- mutate_at(dataset, .vars = yvar, .funs = as.factor) diff --git a/radiant.quickgen/inst/app/init.R b/radiant.quickgen/inst/app/init.R index 403e99a81536a39860cb43289dc517a8c2dfe800..636bf72ef54a9fc557be505ccdc9496f15ec05dd 100644 --- a/radiant.quickgen/inst/app/init.R +++ b/radiant.quickgen/inst/app/init.R @@ -15,7 +15,7 @@ options( tags$script(src = "www_quickgen/js/run_return.js") ), tabPanel(i18n$t("Generate descriptive statistics with one click"), uiOutput("quickgen_basic")), - tabPanel(i18n$t("LLM generates descriptive statistics"), uiOutput("quickgen_ai")) + tabPanel(i18n$t("AI generates descriptive statistics"), uiOutput("quickgen_ai")) ) ) ) \ No newline at end of file diff --git a/radiant.quickgen/inst/app/tools/analysis/quickgen_ai_ui.R b/radiant.quickgen/inst/app/tools/analysis/quickgen_ai_ui.R index 86b2a99816efcd09cb1ebf14bb45ec8d6e643921..72d9270fe42e1b9c0eae0883f6f486d008353469 100644 --- a/radiant.quickgen/inst/app/tools/analysis/quickgen_ai_ui.R +++ b/radiant.quickgen/inst/app/tools/analysis/quickgen_ai_ui.R @@ -1,9 +1,295 @@ -#' 大模型生成描述性统计界面 -quickgen_ai_ui <- function() { +# quickgen_ai_ui.R +library(shinyjs) +library(shinyAce) + +## ==================== 右下角浮框 ==================== +ui_ai_progress <- tags$div( + id = "ai_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(i18n$t("AI running...")), + tags$div(class = "progress", + tags$div(class = "progress-bar progress-bar-striped active", + style = "width:100%")) +) + +## ======== 警告弹窗======== +ui_ai_warn <- tags$div( + id = "ai_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(i18n$t("Warning:Please enter a request related to descriptive statistics or visualization.")) +) + +## ==================== 统一入口 ==================== +output$quickgen_ai <- renderUI({ + stat_tab_panel( + menu = i18n$t("Oneclick generation > AI generates descriptive statistics"), + tool = i18n$t("AI generates descriptive statistics"), + tool_ui = "ai_main_ui", + output_panels = tabPanel( + title = i18n$t("AI assistant"), + value = "ai_panel", + uiOutput("ai_result_area") + ) + ) +}) + +## ==================== 右侧 AI 面板 ==================== +output$ai_main_ui <- renderUI({ tagList( - h3("大模型生成描述性统计"), - p("正在开发中...") + useShinyjs(), + ui_ai_progress, + ui_ai_warn, + wellPanel( + i18n$t("Describe your analysis request"), + returnTextAreaInput("ai_prompt", + label = NULL, + placeholder = i18n$t("e. g. Please help me draw a scatter plot of diamonds prices and carats"), + rows = 4, + value = state_init("ai_prompt", "")), + fluidRow( + column(6, uiOutput("ui_ai_submit")), + column(6, uiOutput("ai_loading")) + ) + ), + + wellPanel( + i18n$t("Generated R code"), + uiOutput("ai_r_code_block"), + fluidRow( + column(6, actionButton("ai_run_code", i18n$t("Run code"), icon = icon("play"), class = "btn-success")), + column(6, actionButton("ai_edit_code", i18n$t("Edit code"), icon = icon("edit"), class = "btn-default")) + ) + ), + + help_and_report( + modal_title = i18n$t("AI generates descriptive statistics"), + fun_name = "quickgen_ai", + help_file = inclMD(file.path(getOption("radiant.path.quickgen"), "app/tools/help/quickgen_ai.md")), + lic = "by-sa" + ) ) +}) + +## ==================== 控件渲染 ==================== +output$ui_ai_submit <- renderUI({ + req(input$dataset) + actionButton("ai_submit", i18n$t("Send"), icon = icon("magic"), class = "btn-primary") +}) + +output$ai_loading <- renderUI({ + if (isTRUE(r_values$ai_loading)) + tags$div(class = "progress", + tags$div(class = "progress-bar progress-bar-striped active", + style = "width:100%", + i18n$t("Calling AI model..."))) +}) + +## ==================== reactiveValues ==================== +r_values <- reactiveValues( + ai_r_code = "", + ai_result_type = "text", + ai_result_ready = FALSE, + ai_loading = FALSE +) + +## ==================== 生成代码 ==================== +observeEvent(input$ai_submit, { + if (is.empty(input$ai_prompt)) + return(showNotification(i18n$t("Please enter an analysis request"), type = "error")) + + r_values$ai_loading <- TRUE + shinyjs::show("ai_progress_box") # 显示右下角进度框 + on.exit({ + r_values$ai_loading <- FALSE + shinyjs::hide("ai_progress_box") # 无论成功失败都隐藏 + }) + + res <- try(do.call(ai_generate, + list(prompt = input$ai_prompt, + dataset = input$dataset, + envir = r_data)), + silent = TRUE) + if (inherits(res, "try-error")) { + showNotification(paste(i18n$t("AI API error:"), res), type = "error") + return() + } + + r_values$ai_r_code <- res$r_code + r_values$ai_result_type <- res$type + r_values$ai_result_ready <- FALSE + r_values$auto_run <- res$auto_run + + if (res$type == "empty") { + shinyjs::show("ai_warn_box") + shinyjs::delay(3000, shinyjs::hide("ai_warn_box")) + return() + } + + if (isTRUE(r_values$auto_run)) + shinyjs::click("ai_run_code") +}) + +## ==================== 显示 R 代码 ==================== +output$ai_r_code_block <- renderUI({ + codes <- r_values$ai_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$ai_run_code, { + shinyjs::hide("ai_progress_box") + if (is.empty(r_values$ai_r_code)) return() + + if (trimws(r_values$ai_r_code) == "" || identical(r_values$ai_result_type, "empty")) { + shinyjs::show("ai_warn_box") + shinyjs::delay(3000, shinyjs::hide("ai_warn_box")) + return() + } + + tryCatch({ + result <- do.call(ai_run_code, + list(r_code = r_values$ai_r_code, envir = r_data)) + r_data$ai_temp_result <- result + + if (inherits(result, "gg") || inherits(result, "ggplot")) { + r_values$ai_result_type <- "plot" + output$ai_result_plot <- renderPlot(print(result)) + } else if (is.data.frame(result) || is.matrix(result)) { + r_values$ai_result_type <- "table" + output$ai_result_table <- DT::renderDataTable( + DT::datatable(result, options = list(scrollX = TRUE, pageLength = 10))) + } else { + r_values$ai_result_type <- "text" + output$ai_result_text <- renderText(capture.output(print(result))) + } + r_values$ai_result_ready <- TRUE + }, error = function(e) { + r_values$ai_result_type <- "error" + output$ai_result_error <- renderText(paste0(i18n$t("Error: "), e$message)) + r_values$ai_result_ready <- TRUE + showNotification(paste0(i18n$t("Run code error: "), e$message), + type = "error", duration = NULL) + }) +}, ignoreInit = TRUE) + +## ======== 结果展示区======== +output$ai_result_area <- renderUI({ + req(r_values$ai_result_ready) + tagList( + conditionalPanel( + condition = "output.ai_result_type == 'plot'", + download_link("dlp_ai_plot"), br(), + plotOutput("ai_result_plot", width = "100%", height = "500px") + ), + conditionalPanel( + condition = "output.ai_result_type == 'table'", + download_link("dlp_ai_table"), br(), + DT::dataTableOutput("ai_result_table") + ), + conditionalPanel( + condition = "output.ai_result_type == 'text' || output.ai_result_type == 'error'", + verbatimTextOutput("ai_result_text") + ) + ) +}) + + +output$ai_result_type <- reactive({ + r_values$ai_result_type +}) + +outputOptions(output, "ai_result_type", suspendWhenHidden = FALSE) + +## ==================== 编辑代码模态框 ==================== +observeEvent(input$ai_edit_code, { + showModal( + modalDialog( + title = i18n$t("Edit R Code"), + size = "l", + footer = tagList( + actionButton("ai_save_code", i18n$t("Save Changes"), class = "btn-primary"), + modalButton(i18n$t("Cancel")) + ), + aceEditor( + "ai_code_editor", + mode = "r", + theme = getOption("radiant.ace_theme", "tomorrow"), + wordWrap = TRUE, + value = r_values$ai_r_code, + placeholder = i18n$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$ai_save_code, { + r_values$ai_r_code <- input$ai_code_editor + r_values$auto_run <- FALSE + removeModal() +}) + +## ==================== PNG 下载处理器 ==================== +dlp_ai_plot <- function(path) { + result <- r_data$ai_temp_result + if (inherits(result, "gg") || inherits(result, "ggplot")) { + png(path, width = 800, height = 500, res = 96) + print(result) + dev.off() + } else { + png(path, width = 400, height = 400) + plot(1, type = "n", axes = FALSE, xlab = "", ylab = "") + text(1, 1, "No plot available", cex = 1.5) + dev.off() + } +} +download_handler( + id = "dlp_ai_plot", + fun = dlp_ai_plot, + fn = function() paste0("plot_", Sys.Date()), + type = "png", + caption = i18n$t("Save AI-generated plot") +) + +# ======== 表格 CSV 下载处理器 ======== +dlp_ai_table <- function(path) { + result <- r_data$ai_temp_result + if (is.data.frame(result)) { + write.csv(result, file = path, row.names = FALSE) + } else { + write.csv(data.frame(msg = "No table available"), file = path, row.names = FALSE) + } } +download_handler( + id = "dlp_ai_table", + fun = dlp_ai_table, + fn = function() paste0("table_", Sys.Date()), + type = "csv", + caption = i18n$t("Save AI-generated table") +) -quickgen_ai_ui() \ No newline at end of file +## ==================== 报告 / 截图 ==================== +ai_report <- function() {} +observeEvent(input$ai_report, ai_report()) +observeEvent(input$ai_screenshot, radiant_screenshot_modal("modal_ai_screenshot")) +observeEvent(input$modal_ai_screenshot, { ai_report(); removeModal() }) \ No newline at end of file diff --git a/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui .txt b/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui .txt deleted file mode 100644 index 45407749489d93afb8c90588c23d461c56f86e1c..0000000000000000000000000000000000000000 --- a/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui .txt +++ /dev/null @@ -1,1115 +0,0 @@ -make_desc_text <- function(df) { - if (is.null(df) || nrow(df) == 0) return(i18n$t("No data available")) - ## 只保留数值列 - num_cols <- sapply(df, is.numeric) - if (sum(num_cols) == 0) return("No numerical variable available") - df_num <- df[, num_cols, drop = FALSE] - - buf <- c(i18n$t("### Current data overview")) - buf <- c(buf, sprintf("- **Sample size**:%d records", nrow(df))) - ## 连续变量 - for (v in names(df_num)) { - x <- df_num[[v]] - x <- x[!is.na(x)] - if (length(x) == 0) next - buf <- c(buf, sprintf( - "- **%s**: mean %.2f ± %.2f; median %.2f; range [%.2f, %.2f]; missing %.1f%%", - v, - mean(x), sd(x), median(x), min(x), max(x), - 100 * (1 - length(x) / nrow(df)) - )) - } - ## 分类变量 - cat_cols <- sapply(df, function(z) is.factor(z) || is.character(z)) - for (v in names(df)[cat_cols]) { - tbl <- table(df[[v]], useNA = "ifany") - lev_txt <- paste(sprintf("%s (%d, %.1f%%)", - names(tbl), tbl, - 100 * tbl / sum(tbl)), collapse = "、") - buf <- c(buf, sprintf("- **%s**:%s", v, lev_txt)) - } - paste(buf, collapse = "\n") -} - -## quickgen_basic 的形参列表 -default_funs <- c("n_obs", "mean", "sd", "min", "max") -qib_type <- c( - "分布图(dist)" = "dist", "密度图(density)" = "density", "散点图(scatter)" = "scatter", - "曲面图(surface)" = "surface", "折线图(line)" = "line", "条形图(bar)" = "bar", "箱线图(box)" = "box" -) -qib_check <- c( - "直线(line)" = "line", "局部加权回归(loess)" = "loess", - "抖动(jitter)" = "jitter", - "插值(interpolate)" = "interpolate" -) -qib_axes <- c( - "翻转坐标轴(flip)" = "flip", "X轴对数变换(log_x)" = "log_x", "Y轴对数变换(log_y)" = "log_y", - "Y轴缩放(scale_y)" = "scale_y", "密度(density)" = "density", "排序(sort)" = "sort" -) -qib_theme <- c( - "灰色主题(gray)" = "theme_gray", "黑白主题(bw)" = "theme_bw", - "明亮主题(light)" = "theme_light", "暗黑主题(dark)" = "theme_dark", - "极简主题(minimal)" = "theme_minimal", "经典主题(classic)" = "theme_classic" -) - -os_type <- Sys.info()["sysname"] -if (os_type == "Windows") { - fnt <- names(windowsFonts()) - names(fnt) <- tools::toTitleCase(fnt) - qib_base_family <- c("Theme default" = "", fnt) -} else { - qib_base_family <- c( - "Theme default" = "", "Helvetica" = "Helvetica", "Serif" = "serif", - "Sans" = "sans", "Mono" = "mono", "Courier" = "Courier", "Times" = "Times" - ) -} - -qib_labs <- c(i18n$t("title"), i18n$t("subtitle"), i18n$t("caption"), i18n$t("x"), i18n$t("y")) -qib_add_labs <- function() { - lab_list <- list() - for (l in qib_labs) { - inp <- input[[paste0("qib_labs_", l)]] - if (!is.empty(inp)) lab_list[[l]] <- inp - } - lab_list -} - -qgb_args <- as.list(formals(explore)) -qib_args <- as.list(formals(visualize)) - -## 收集用户输入的 reactive 列表 -qgb_inputs <- reactive({ - qgb_args$data_filter <- if (input$show_filter) input$data_filter else "" - qgb_args$arr <- if (input$show_filter) input$data_arrange else "" - qgb_args$rows <- if (input$show_filter) input$data_rows else "" - qgb_args$dataset <- input$dataset - - for (i in r_drop(names(qgb_args))) { - qgb_args[[i]] <- input[[paste0("qgb_", i)]] - } - qgb_args -}) - -qgb_sum_args <- as.list(if (exists("summary.explore")) { - formals(summary.explore) -} else { - formals(radiant.data:::summary.explore) -}) - -qib_inputs <- reactive({ - qib_args$data_filter <- if (isTRUE(input$show_filter)) input$data_filter else "" - qib_args$arr <- if (isTRUE(input$show_filter)) input$data_arrange else "" - qib_args$rows <- if (isTRUE(input$show_filter)) input$data_rows else "" - qib_args$dataset <- input$dataset - qib_args$shiny <- input$shiny - qib_args$labs <- qib_add_labs() - for (i in r_drop(names(qib_args), drop = c(i18n$t("dataset"), i18n$t("data_filter"), i18n$t("arr"), i18n$t("rows"), i18n$t("labs")))) { - qib_args[[i]] <- input[[paste0("qib_", i)]] - } - qib_args -}) - -## list of function inputs selected by user -qgb_sum_inputs <- reactive({ - ## loop needed because reactive values don't allow single bracket indexing - for (i in names(qgb_sum_args)) { - qgb_sum_args[[i]] <- input[[paste0("qgb_", i)]] - } - qgb_sum_args -}) - -## UI-elements -output$ui_qgb_vars <- renderUI({ - vars <- varnames() - req(available(vars)) - selectizeInput( - "qgb_vars", - label = i18n$t("Numeric variable(s):"), - choices = vars, - selected = state_multiple("qgb_vars", vars, isolate(input$qgb_vars)), - multiple = TRUE, - options = list( - placeholder = i18n$t("Select numeric variables"), - plugins = list("remove_button", "drag_drop") - ) - ) -}) - -output$ui_qgb_byvar <- renderUI({ - withProgress(message = i18n$t("Acquiring variable information"), value = 1, { - vars <- groupable_vars() - }) - req(available(vars)) - - if (any(vars %in% input$qgb_vars)) { - vars <- base::setdiff(vars, input$qgb_vars) - names(vars) <- varnames() %>% - (function(x) x[match(vars, x)]) %>% - names() - } - isolate({ - ## if nothing is selected expl_byvar is also null - if ("qgb_byvar" %in% names(input) && is.null(input$qgb_byvar)) { - r_state$qgb_byvar <<- NULL - } else { - if (available(r_state$qgb_byvar) && all(r_state$qgb_byvar %in% vars)) { - vars <- unique(c(r_state$qgb_byvar, vars)) - names(vars) <- varnames() %>% - (function(x) x[match(vars, x)]) %>% - names() - } - } - }) - selectizeInput( - "qgb_byvar", - label = i18n$t("Group by:"), choices = vars, - selected = state_multiple("qgb_byvar", vars, isolate(input$qgb_byvar)), - multiple = TRUE, - options = list( - placeholder = i18n$t("Select group-by variable"), - plugins = list("remove_button", "drag_drop") - ) - ) -}) - -output$ui_qgb_fun <- renderUI({ - r_funs <- getOption("radiant.functions") - selected <- isolate( - if (is.empty(input$qgb_fun)) default_funs else input$qgb_fun - ) - tagList( - div( - style = "margin-top: 5px; display: flex; gap: 3px; flex-wrap: wrap;", - actionButton("qgb_select_all", i18n$t("Select All"), - class = "btn-xs btn-primary", icon = icon("check-square")), - actionButton("qgb_deselect_all", i18n$t("Deselect All"), - class = "btn-xs btn-primary", icon = icon("square")), - actionButton("qgb_invert_selection", i18n$t("Invert"), - class = "btn-xs btn-primary", icon = icon("undo")) - ), - checkboxGroupInput( - inputId = "qgb_fun", - label = i18n$t("Apply function(s):"), - choices = r_funs, - selected = selected - ) - ) -}) - -output$ui_qgb_top <- renderUI({ - if (is.empty(input$qgb_vars)) { - return() - } - top_var <- setNames( - c("fun", "var", "byvar"), - c(i18n$t("Function"), i18n$t("Variables"), i18n$t("Group by")) - ) - if (is.empty(input$qgb_byvar)) top_var <- top_var[1:2] - selectizeInput( - "qgb_top", - label = i18n$t("Column header:"), - choices = top_var, - selected = state_single("qgb_top", top_var, isolate(input$qgb_top)), - multiple = FALSE - ) -}) - -output$ui_qgb_name <- renderUI({ - req(input$dataset) - textInput("qgb_name", i18n$t("Store as:"), "", placeholder = i18n$t("Provide a table name")) -}) - -output$ui_qgb_run <- renderUI({ - ## updates when dataset changes - req(input$dataset) - actionButton("qgb_run", i18n$t("OneClick table generation"), width = "100%", icon = icon("play", verify_fa = FALSE), class = "btn-success") -}) - -## add a spinning refresh icon if the table needs to be (re)calculated -run_refresh(qgb_args, "qgb", init = "vars", label = i18n$t("OneClick table generation"), relabel = i18n$t("Update table")) - -####################################### -# Visualize data -####################################### -output$ui_qib_type <- renderUI({ - selectInput( - inputId = "qib_type", label = i18n$t("Plot-type:"), choices = qib_type, - selected = state_single("qib_type", qib_type), - multiple = FALSE - ) -}) - -output$ui_qib_nrobs <- renderUI({ - req(input$qib_type == "scatter") - nrobs <- nrow(.get_data()) - choices <- c("1,000" = 1000, "5,000" = 5000, "10,000" = 10000, "All" = -1) %>% - .[. < nrobs] - selectInput( - "qib_nrobs", i18n$t("Number of data points plotted:"), - choices = choices, - selected = state_single("qib_nrobs", choices, 1000) - ) -}) - -## Y - variable -output$ui_qib_yvar <- renderUI({ - req(input$qib_type) - vars <- varying_vars() - req(available(vars)) - vars <- vars["date" != .get_class()[vars]] - if (input$qib_type %in% c("line", "bar", "scatter", "surface", "box")) { - vars <- vars["character" != .get_class()[vars]] - } - if (input$qib_type %in% c("box", "scatter")) { - vars <- vars["factor" != .get_class()[vars]] - } - - selectizeInput( - inputId = "qib_yvar", - label = i18n$t("Y-variable:"), - choices = vars, - selected = state_multiple("qib_yvar", vars, isolate(input$qib_yvar)), - multiple = TRUE, - options = list( - placeholder = i18n$t("Select Y variable(s)"), - plugins = list("remove_button", "drag_drop") - ) - ) -}) - -## X - variable -output$ui_qib_xvar <- renderUI({ - req(input$qib_type) - vars <- varying_vars() - req(available(vars)) - if (input$qib_type == "dist") vars <- vars["date" != .get_class()[vars]] - if (input$qib_type == "density") vars <- vars["factor" != .get_class()[vars]] - if (input$qib_type %in% c("box", "bar")) vars <- groupable_vars_nonum() - - selectizeInput( - inputId = "qib_xvar", - label = i18n$t("X-variable:"), - choices = vars, - selected = state_multiple("qib_xvar", vars, isolate(input$qib_xvar)), - multiple = TRUE, - options = list( - placeholder = i18n$t("Select X variable(s)"), - plugins = list("remove_button", "drag_drop") - ) - ) -}) - -output$ui_qib_comby <- renderUI({ - checkboxInput( - "qib_comby", i18n$t("Combine Y-variables in one plot"), - state_init("qib_comby", FALSE) - ) -}) - -output$ui_qib_combx <- renderUI({ - checkboxInput( - "qib_combx", i18n$t("Combine X-variables in one plot"), - state_init("qib_combx", FALSE) - ) -}) - -observeEvent(length(input$qib_xvar) < 2, { - updateCheckboxInput(session, "qib_combx", value = FALSE) -}) - -observeEvent(length(input$qib_yvar) < 2, { - updateCheckboxInput(session, "qib_comby", value = FALSE) -}) - -observeEvent(input$qib_type, { - if (input$qib_type %in% c("dist", "density")) { - updateCheckboxInput(session, "qib_comby", value = FALSE) - } else { - updateCheckboxInput(session, "qib_combx", value = FALSE) - } -}) - -observeEvent(input$qib_check, { - if (!"loess" %in% input$qib_check && input$qib_smooth != 1) { - updateSliderInput(session, "qib_smooth", value = 1) - } -}) - -# output$ui_qib_facet_row <- renderUI({ -# vars <- c("None" = ".", groupable_vars_nonum()) -# selectizeInput( -# "qib_facet_row", i18n$t("Facet row:"), vars, -# selected = state_single("qib_facet_row", vars, init = "."), -# multiple = FALSE -# ) -# }) - -# output$ui_qib_facet_col <- renderUI({ -# vars <- c("None" = ".", groupable_vars_nonum()) -# selectizeInput( -# "qib_facet_col", i18n$t("Facet column:"), vars, -# selected = state_single("qib_facet_col", vars, init = "."), -# multiple = FALSE -# ) -# }) - -# output$ui_qib_color <- renderUI({ -# req(input$qib_type) -# if (input$qib_type == "line") { -# vars <- c("None" = "none", groupable_vars()) -# } else { -# vars <- c("None" = "none", varnames()) -# } -# -# if (isTRUE(input$qib_comby) && length(input$qib_yvar) > 1) vars <- c("None" = "none") -# selectizeInput( -# "qib_color", i18n$t("Color:"), vars, -# multiple = FALSE, -# selected = state_single("qib_color", vars, init = "none") -# ) -# }) - -# output$ui_qib_fill <- renderUI({ -# vars <- c("None" = "none", groupable_vars()) -# if (isTRUE(input$qib_combx) && length(input$qib_xvar) > 1) vars <- vars[1] -# selectizeInput( -# "qib_fill", i18n$t("Fill:"), vars, -# multiple = FALSE, -# selected = state_single("qib_fill", vars, init = "none") -# ) -# }) - -# output$ui_qib_size <- renderUI({ -# req(input$qib_type) -# isNum <- .get_class() %in% c("integer", "numeric", "ts") -# vars <- c("None" = "none", varnames()[isNum]) -# if (isTRUE(input$qib_comby) && length(input$qib_yvar) > 1) vars <- c("None" = "none") -# selectizeInput( -# "qib_size", i18n$t("Size:"), vars, -# multiple = FALSE, -# selected = state_single("qib_size", vars, init = "none") -# ) -# }) - -output$ui_qib_axes <- renderUI({ - req(input$qib_type) - ind <- 1 - if (input$qib_type %in% c("line", "scatter", "surface")) { - ind <- 1:3 - } else if (input$qib_type == "dist") { - ind <- c(1:2, 5) - } else if (input$qib_type == "density") { - ind <- 1:2 - } else if (input$qib_type %in% c("bar", "box")) { - ind <- c(1, 3) - } - if (!is.empty(input$qib_facet_row, ".") || !is.empty(input$qib_facet_col, ".")) ind <- c(ind, 4) - if (input$qib_type == "bar") ind <- c(ind, 6) - - checkboxGroupInput( - "qib_axes", NULL, qib_axes[ind], - selected = state_group("qib_axes", ""), - inline = TRUE - ) -}) - -output$ui_qib_check <- renderUI({ - req(input$qib_type) - if (input$qib_type == "scatter") { - ind <- 1:3 - } else if (input$qib_type == "box") { - ind <- 3 - } else if (input$qib_type == "surface") { - ind <- 4 - } else { - ind <- c() - } - - if (!input$qib_type %in% c("scatter", "box")) { - r_state$qib_check <<- gsub("jitter", "", r_state$qib_check) - } - if (input$qib_type != "scatter") { - r_state$qib_check <<- gsub("line", "", r_state$qib_check) - r_state$qib_check <<- gsub("loess", "", r_state$qib_check) - } - - checkboxGroupInput( - "qib_check", NULL, qib_check[ind], - selected = state_group("qib_check", ""), - inline = TRUE - ) -}) - -output$ui_qib_run <- renderUI({ - req(input$dataset) - actionButton("qib_run", i18n$t("OneClick chart generation"), width = "100%", icon = icon("play", verify_fa = FALSE), class = "btn-success") -}) - -# output$ui_qib_labs <- renderUI({ -# ## updates when dataset changes -# req(input$dataset) -# wellPanel( -# textAreaInput("qib_labs_title", NULL, "", placeholder = i18n$t("Title"), rows = 1), -# textAreaInput("qib_labs_subtitle", NULL, "", placeholder = i18n$t("Subtitle"), rows = 1), -# textAreaInput("qib_labs_caption", NULL, "", placeholder = i18n$t("Caption"), rows = 1), -# textAreaInput("qib_labs_y", NULL, "", placeholder = i18n$t("Y-label"), rows = 1), -# textAreaInput("qib_labs_x", NULL, "", placeholder = i18n$t("X-label"), rows = 1) -# ) -# }) - -output$ui_qib_colors <- renderUI({ - tagList( - conditionalPanel( - condition = "input.qib_type == 'bar' || - input.qib_type == 'dist' || - input.qib_type == 'box' || - input.qib_type == 'density'", - selectInput( - "qib_fillcol", i18n$t("Fill color:"), - choices = colors(), - selected = state_single("qib_fillcol", colors(), "blue") - ) - ), - conditionalPanel( - condition = "input.qib_type == 'dist' || - input.qib_type == 'density' || - input.qib_type == 'box' || - input.qib_type == 'scatter' || - input.qib_type == 'line'", - selectInput( - "qib_linecol", i18n$t("Line color:"), - choices = colors(), - selected = state_single("qib_linecol", colors(), "black") - ) - ), - conditionalPanel( - condition = "input.qib_type == 'scatter' || - input.qib_type == 'line' || - input.qib_type == 'box'", - selectInput( - "qib_pointcol", i18n$t("Point color:"), - choices = colors(), - selected = state_single("qib_pointcol", colors(), "black") - ) - ) - ) -}) - -run_refresh( - qib_args, "qib", - init = c("xvar", "yvar"), label = i18n$t("OneClick chart generation"), relabel = i18n$t("Update plot"), - inputs = c("labs_title", "labs_subtitle", "labs_caption", "labs_y", "labs_x") -) - - -output$ui_quickgen_basic <- renderUI({ - tagList( - wellPanel( - uiOutput("ui_qgb_run") - ), - checkboxInput("qgb_details_table", i18n$t("Table"), state_init("qgb_details_table", FALSE)), - conditionalPanel( - "input.qgb_details_table == true", - wellPanel( - uiOutput("ui_qgb_vars"), - uiOutput("ui_qgb_byvar"), - uiOutput("ui_qgb_top"), - # returnTextAreaInput("qgb_tab_slice", - # label = i18n$t("Table slice (rows):"), - # rows = 1, - # value = state_init("qgb_tab_slice"), - # placeholder = i18n$t("e.g., 1:5 and press return") - # ), - uiOutput("ui_qgb_fun"), - numericInput("qgb_dec", label = i18n$t("Decimals:"), value = state_init("qgb_dec", 3), min = 0), - tags$table( - tags$td(uiOutput("ui_qgb_name")), - tags$td(actionButton("qgb_store", i18n$t("Store"), icon = icon("plus", verify_fa = FALSE)), class = "top") - ) - ), - ), - wellPanel( - uiOutput("ui_qib_run") - ), - checkboxInput("qib_details_chart", i18n$t("Chart"), state_init("qib_details_chart", FALSE)), - conditionalPanel( - "input.qib_details_chart == true", - wellPanel( - uiOutput("ui_qib_type"), - conditionalPanel( - "input.qib_type == 'scatter'", - uiOutput("ui_qib_nrobs") - ), - conditionalPanel( - condition = "input.qib_type != 'dist' && input.qib_type != 'density'", - uiOutput("ui_qib_yvar"), - conditionalPanel( - "input.qib_yvar != undefined && input.qib_yvar != null && input.qib_yvar.length > 1", - uiOutput("ui_qib_comby") - ) - ), - uiOutput("ui_qib_xvar"), - conditionalPanel( - "input.qib_type == 'dist' || input.qib_type == 'density'", - conditionalPanel( - "input.qib_xvar != undefined && input.qib_xvar != null && input.qib_xvar.length > 1", - uiOutput("ui_qib_combx") - ) - ), - # uiOutput("ui_qib_facet_row"), - # uiOutput("ui_qib_facet_col"), - # conditionalPanel( - # condition = "input.qib_type == 'bar' || - # input.qib_type == 'dist' || - # input.qib_type == 'density' || - # input.qib_type == 'surface'", - # uiOutput("ui_qib_fill") - # ), - # conditionalPanel( - # condition = "input.qib_type == 'scatter' || - # input.qib_type == 'line' || - # input.qib_type == 'box'", - # uiOutput("ui_qib_color") - # ), - # conditionalPanel( - # condition = "input.qib_type == 'scatter'", - # uiOutput("ui_qib_size") - # ), - conditionalPanel( - condition = "input.qib_type == 'bar' || - input.qib_type == 'scatter' || - input.qib_type == 'line'", - selectInput( - "qib_fun", i18n$t("Function:"), - choices = getOption("radiant.functions"), - selected = state_single("qib_fun", getOption("radiant.functions"), "mean") - ) - ), - # conditionalPanel( - # condition = "input.qib_type == 'scatter' || - # input.qib_type == 'line' || - # input.qib_type == 'surface' || - # input.qib_type == 'box'", - # uiOutput("ui_qib_check") - # ), - # uiOutput("ui_qib_axes"), - conditionalPanel( - condition = "input.qib_type == 'dist'", - sliderInput( - "qib_bins", - label = i18n$t("Number of bins:"), - value = state_init("qib_bins", 10), - min = 2, max = 50, step = 1 - ) - ), - conditionalPanel( - "input.qib_type == 'density' || - input.qib_type == 'dist' && (input.qib_axes && input.qib_axes.indexOf('density')) >= 0 || - (input.qib_type == 'scatter' && (input.qib_check && input.qib_check.indexOf('loess') >= 0))", - sliderInput( - "qib_smooth", - label = i18n$t("Smooth:"), - value = state_init("qib_smooth", 1), - min = 0.1, max = 3, step = .1 - ) - ) - ) - ), - # checkboxInput("qib_details_labels", i18n$t("Labels"), state_init("qib_details_labels", FALSE)), - # conditionalPanel( - # "input.qib_details_labels == true", - # uiOutput("ui_qib_labs") - # ), - checkboxInput("qib_details_style", i18n$t("Style"), state_init("qib_details_style", FALSE)), - conditionalPanel( - "input.qib_details_style == true", - wellPanel( - selectInput( - "qib_theme", i18n$t("Plot theme:"), - choices = qib_theme, - selected = state_single("qib_theme", qib_theme, "theme_gray") - ), - numericInput( - "qib_base_size", i18n$t("Base font size:"), - value = state_init("qib_base_size", 11) - ), - selectInput( - "qib_base_family", i18n$t("Font family:"), - choices = qib_base_family, - selected = state_single("qib_base_family", qib_base_family, "helvetica") - ), - uiOutput("ui_qib_colors"), - sliderInput( - "qib_alpha", - label = i18n$t("Opacity:"), - value = state_init("qib_alpha", .5), - min = 0, max = 1, step = .01 - ), - tags$table( - tags$td( - numericInput( - "qib_plot_height", - label = i18n$t("Plot height:"), min = 100, - max = 2000, step = 50, - value = state_init("qib_plot_height", r_info[["plot_height"]]), - width = "117px" - ) - ), - tags$td( - numericInput( - "qib_plot_width", - label = i18n$t("Plot width:"), min = 100, - max = 2000, step = 50, - value = state_init("qib_plot_width", r_info[["plot_width"]]), - width = "117px" - ), - width = "100%" - ) - ) - ) - ), - help_and_report( - modal_title = i18n$t("Generate descriptive statistics with one click"), fun_name = "quickgen_basic", - help_file = inclMD(file.path(getOption("radiant.path.quickgen"), "app/tools/help/quickgen_basic.md")), - lic = "by-sa" - ) - ) -}) - -qib_plot_width <- reactive({ - if (is.empty(input$qib_plot_width)) r_info[["plot_width"]] else input$qib_plot_width -}) - -qib_plot_height <- eventReactive( - { - input$qib_run - input$qib_plot_height - input$qib_plot_width - }, - { - if (is.empty(input$qib_plot_height)) { - r_info[["plot_height"]] - } else { - lx <- ifelse(not_available(input$qib_xvar) || isTRUE(input$qib_combx), 1, length(input$qib_xvar)) - ly <- ifelse(not_available(input$qib_yvar) || input$qib_type %in% c("dist", "density") || - isTRUE(input$qib_comby), 1, length(input$qib_yvar)) - nr <- lx * ly - if (nr > 1) { - (input$qib_plot_height / 2) * ceiling(nr / 2) - } else { - input$qib_plot_height - } - } - } -) - -.quickgen <- eventReactive(input$qgb_run, { - if (not_available(input$qgb_vars) || is.null(input$qgb_top)) { - return() - } else if (!is.empty(input$qgb_byvar) && not_available(input$qgb_byvar)) { - return() - } else if (available(input$qgb_byvar) && any(input$qgb_byvar %in% input$qgb_vars)) { - return() - } - qgbi <- qgb_inputs() - qgbi$envir <- r_data - sshhr(do.call(explore, qgbi)) -}) - -observeEvent(input$qgb_search_columns, { - r_state$qgb_search_columns <<- input$qgb_search_columns -}) - -observeEvent(input$qgb_state, { - r_state$qgb_state <<- input$qgb_state -}) - - -qgb_reset <- function(var, ncol) { - if (!identical(r_state[[var]], input[[var]])) { - r_state[[var]] <<- input[[var]] - r_state$qgb_state <<- list() - r_state$qgb_search_columns <<- rep("", ncol) - } -} - -output$qgb_tab <- DT::renderDataTable({ - input$qgb_run - withProgress(message = i18n$t("Generating explore table"), value = 1, { - isolate({ - qgb <- .quickgen() - req(!is.null(qgb)) - qgb$shiny <- TRUE - - ## resetting DT when changes occur - nc <- ncol(qgb$tab) - qgb_reset("qgb_vars", nc) - qgb_reset("qgb_byvar", nc) - qgb_reset("qgb_fun", nc) - if (!is.null(r_state$qgb_top) && - !is.null(input$qgb_top) && - !identical(r_state$qgb_top, input$qgb_top)) { - r_state$qgb_top <<- input$qgb_top - r_state$qgb_state <<- list() - r_state$qgb_search_columns <<- rep("", nc) - } - - searchCols <- lapply(r_state$qgb_search_columns, function(x) list(search = x)) - order <- r_state$qgb_state$order - pageLength <- r_state$qgb_state$length - }) - - caption <- if (is.empty(input$qgb_tab_slice)) NULL else glue("Table slice {input$expl_tab_slice} will be applied on Download, Store, or Report") - dtab( - qgb, - dec = input$qgb_dec, searchCols = searchCols, order = order, - pageLength = pageLength, - caption = caption - ) - }) -}) - -dl_qgb_tab <- function(path) { - dat <- try(.quickgen(), silent = TRUE) - if (inherits(dat, "try-error") || is.null(dat)) { - write.csv(tibble::tibble("Data" = "[Empty]"), path, row.names = FALSE) - return() - } - - rows <- input$qgb_rows_all - tmp <- if (is.null(rows)) dat$tab else dat$tab[rows, , drop = FALSE] - - if (is.null(tmp) || nrow(tmp) == 0) { - write.csv(tibble::tibble("Data" = "[Empty]"), path, row.names = FALSE) - } else { - write.csv(tmp, path, row.names = FALSE) - } -} - - -output$qib_chart <- renderPlot( - { - req(input$qib_type) - if (not_available(input$qib_xvar)) { - if (!input$qib_type %in% c("box", "line")) { - return( - plot( - x = 1, type = "n", - main = " ", - axes = FALSE, xlab = "", ylab = "", cex.main = .9 - ) - ) - } - } - .qib_chart() %>% - (function(x) { - if (is.empty(x) || is.character(x)) { - plot(x = 1, type = "n", main = paste0("\n", x), axes = FALSE, xlab = "", ylab = "", cex.main = .9) - } else if (length(x) > 0) { - print(x) - } - }) - }, - width = qib_plot_width, - height = qib_plot_height, - res = 96 -) - -.qib_chart <- eventReactive(input$qib_run, { - req(input$qib_type) - if (input$qib_type == "scatter") req(input$qib_nrobs) - - ## need dependency on .. - req(input$qib_plot_height && input$qib_plot_width) - - if (not_available(input$qib_xvar) && !input$qib_type %in% c("box", "line")) { - return() - } else if (input$qib_type %in% c("scatter", "line", "box", "bar", "surface") && not_available(input$qib_yvar)) { - return(i18n$t("No Y-variable provided for a plot that requires one")) - } else if (input$qib_type == "box" && !all(input$qib_xvar %in% groupable_vars())) { - return() - } - - ## waiting for comby and/or combx to be updated - if (input$qib_type %in% c("dist", "density")) { - if (isTRUE(input$qib_comby)) { - return() - } - if (length(input$qib_xvar) > 1 && is.null(input$qib_combx)) { - return() - } - } else { - if (isTRUE(input$qib_combx)) { - return() - } - if (length(input$qib_yvar) > 1 && is.null(input$qib_comby)) { - return() - } - } - - #req(!is.null(input$qib_color) || !is.null(input$qib_fill)) - qibi <- qib_inputs() - qibi$dataset <- input$dataset - qibi$shiny <- TRUE - qibi$envir <- r_data - qibi$color <- "none" - qibi$fill <- "none" - qibi$facet_row <- "." - qibi$facet_col <- "." - withProgress(message = i18n$t("Making plot"), value = 1, { - do.call(visualize, qibi) - }) -}) - -observeEvent(input$qgb_store, { - req(input$qgb_name) - dat <- .quickgen() - if (is.null(dat)) { - return() - } - dataset <- fix_names(input$qgb_name) - if (input$qgb_name != dataset) { - updateTextInput(session, inputId = "qgb_name", value = dataset) - } - rows <- input$qgb_rows_all - tmp <- if (is.null(rows)) dat$tab else dat$tab[rows, , drop = FALSE] - r_data[[dataset]] <- tmp - register(dataset) - updateSelectInput(session, "dataset", selected = input$dataset) - - showModal( - modalDialog( - title = i18n$t("Data Stored"), - span( - i18n$t("Dataset was successfully added to the datasets dropdown. Add code to Report > Rmd or Report > R to (re)create the results by clicking the report icon on the bottom left of your screen.") - ), - footer = modalButton(i18n$t("OK")), - size = "m", - easyClose = TRUE - ) - ) -}) - -qgb_report <- function() { - ## get the state of the dt table - ts <- dt_state("qgb_tab") - xcmd <- "# summary(result)\ndtab(result" - if (!is.empty(input$qgb_dec, 3)) { - xcmd <- paste0(xcmd, ", dec = ", input$qgb_dec) - } - if (!is.empty(r_state$qgb_state$length, 10)) { - xcmd <- paste0(xcmd, ", pageLength = ", r_state$qgb_state$length) - } - xcmd <- paste0(xcmd, ", caption = \"\") %>% render()") - if (!is.empty(input$qgb_name)) { - dataset <- fix_names(input$qgb_name) - if (input$qgb_name != dataset) { - updateTextInput(session, inputId = "qgb_name", value = dataset) - } - xcmd <- paste0(xcmd, "\n", dataset, " <- result$tab\nregister(\"", dataset, "\")") - } - - inp_main <- clean_args(qgb_inputs(), qgb_args) - if (ts$tabsort != "") inp_main <- c(inp_main, tabsort = ts$tabsort) - if (ts$tabfilt != "") inp_main <- c(inp_main, tabfilt = ts$tabfilt) - if (is.empty(inp_main$rows)) { - inp_main$rows <- NULL - } - if (is.empty(input$qgb_tab_slice)) { - inp_main <- c(inp_main, nr = Inf) - } else { - inp_main$tabslice <- input$qgb_tab_slice - } - - inp_out <- list(clean_args(qgb_sum_inputs(), qgb_sum_args[-1])) - - update_report( - inp_main = inp_main, - fun_name = "qgb", - inp_out = inp_out, - outputs = c(), - figs = FALSE, - xcmd = xcmd - ) -} - -qib_report <- function() { - ## resetting hidden elements to default values - vi <- qib_inputs() - if (input$qib_type != "dist") { - vi$bins <- qib_args$bins - } - if (input$qib_type %in% c("dist", "density")) { - vi$yvar <- qib_args$yvar - } - if (!input$qib_type %in% c("density", "scatter", "dist") || - !("loess" %in% input$qib_check || "density" %in% input$qib_axes || input$qib_type == "density")) { - vi$smooth <- qib_args$smooth - } - if (!input$qib_type %in% c("scatter", "box") && "jitter" %in% input$qib_check) { - vi$check <- base::setdiff(vi$check, "jitter") - } - if (input$qib_type != "scatter") { - vi$size <- "none" - vi$nrobs <- NULL - } else { - vi$nrobs <- as_integer(vi$nrobs) - } - if (!input$qib_type %in% c("scatter", "line", "box")) { - vi$color <- NULL - } - if (!input$qib_type %in% c("bar", "dist", "density", "surface")) { - vi$fill <- NULL - } - - if (!input$qib_type %in% c("bar", "dist", "box", "density")) { - vi$fillcol <- "blue" - } - if (!input$qib_type %in% c("dist", "density", "box", "scatter", "line")) { - vi$linecol <- "black" - } - if (!input$qib_type %in% c("box", "scatter", "line")) { - vi$pointcol <- "black" - } - - if (!input$qib_type %in% c("bar", "line", "scatter")) { - vi$fun <- "mean" - } - if (is.empty(input$data_rows)) { - vi$rows <- NULL - } - - inp_main <- c(clean_args(vi, qib_args), custom = FALSE) - - update_report( - inp_main = inp_main, - fun_name = "qib_chart", - outputs = character(0), - pre_cmd = "", - figs = TRUE, - fig.width = qib_plot_width(), - fig.height = qib_plot_height() - ) -} - -download_handler( - id = "dl_qgb_tab", - fun = dl_qgb_tab, - fn = function() paste0(input$dataset, "_tab"), - type = "csv" -) - -download_handler( - id = "dlp_qib_chart", - fun = download_handler_plot, - fn = function() paste0(input$dataset, "_chart"), - type = "png", - caption = i18n$t("Save visualize plot"), - plot = .qib_chart, - width = qib_plot_width, - height = qib_plot_height -) - - -observeEvent(input$qgb_report, { - r_info[["latest_screenshot"]] <- NULL - qgb_report() -}) - -observeEvent(input$qgb_screenshot, { - r_info[["latest_screenshot"]] <- NULL - radiant_screenshot_modal("modal_qgb_screenshot") -}) - -observeEvent(input$modal_qgb_screenshot, { - qgb_report() - removeModal() -}) - -observeEvent(input$qib_report, { - r_info[["latest_screenshot"]] <- NULL - qib_report() -}) - -observeEvent(input$qib_screenshot, { - r_info[["latest_screenshot"]] <- NULL - radiant_screenshot_modal("modal_qib_screenshot") -}) - -observeEvent(input$modal_qib_screenshot, { - qib_report() - removeModal() -}) - -# 全选功能 -observeEvent(input$qgb_select_all, { - r_funs <- getOption("radiant.functions") - if (!is.null(r_funs)) { - updateCheckboxGroupInput(session, "qgb_fun", selected = r_funs) - } -}) - -# 全不选功能 -observeEvent(input$qgb_deselect_all, { - updateCheckboxGroupInput(session, "qgb_fun", selected = character(0)) -}) - -# 反选功能 -observeEvent(input$qgb_invert_selection, { - current <- input$qgb_fun %||% character(0) - r_funs <- getOption("radiant.functions") - if (!is.null(r_funs)) { - new_selection <- setdiff(r_funs, current) - updateCheckboxGroupInput(session, "qgb_fun", selected = new_selection) - } -}) - -output$quickgen_basic <- renderUI({ - stat_tab_panel( - menu = i18n$t("Oneclick generation > Generate descriptive statistics"), - tool = i18n$t("Generate descriptive statistics with one click"), - tool_ui = "ui_quickgen_basic", - output_panels = tagList( - tabPanel( - title = i18n$t("Table"), - download_link("dl_qgb_tab"),br(), - DT::dataTableOutput("qgb_tab"), - tags$hr(), - htmlOutput("qgb_desc_text", inline = FALSE) - ), - tabPanel( - title = i18n$t("Chart"), - download_link("dlp_qib_chart"), br(), - plotOutput("qib_chart", width = "100%", height = "auto"), - tags$hr(), - htmlOutput("qib_desc_text", inline = FALSE) - ) - ) - ) -}) - -## ---------- 表格的描述文字 ---------- -output$qgb_desc_text <- renderUI({ - dat <- tryCatch(.quickgen(), error = function(e) NULL) - txt <- if (!is.null(dat) && !is.null(dat$tab)) { - make_desc_text(dat$tab) - } else { - " " - } - HTML(markdown::markdownToHTML(text = txt, fragment.only = TRUE)) -}) - -## ---------- 图表的描述文字 ---------- -output$qib_desc_text <- renderUI({ - df <- tryCatch({ - qibi <- qib_inputs() - qibi$envir <- r_data - qibi$dataset <- input$dataset - qibi$shiny <- TRUE - res <- do.call(visualize, qibi) - res$data - }, error = function(e) NULL) - - txt <- if (!is.null(df)) make_desc_text(df) else " " - HTML(markdown::markdownToHTML(text = txt, fragment.only = TRUE)) -}) \ No newline at end of file diff --git a/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R b/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R index 9d84af288c148b983300a3ff6b45109c4362f244..d033c6daa3f002f23c9c28b63c297520643ebfd0 100644 --- a/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R +++ b/radiant.quickgen/inst/app/tools/analysis/quickgen_basic_ui.R @@ -1,3 +1,8 @@ +safe_is_empty <- function(x) { + if (is.null(x) || !is.character(x)) return(TRUE) + is.empty(x) +} + make_desc_text <- function(df) { if (is.null(df) || nrow(df) == 0) return(i18n$t("No data available")) num_cols <- sapply(df, is.numeric) @@ -68,7 +73,7 @@ qib_add_labs <- function() { lab_list <- list() for (l in qib_labs) { inp <- input[[paste0("qib_labs_", l)]] - if (!is.empty(inp)) lab_list[[l]] <- inp + if (!safe_is_empty(inp)) lab_list[[l]] <- inp } lab_list } @@ -402,7 +407,7 @@ output$ui_qib_axes <- renderUI({ } else if (input$qib_type %in% c("bar", "box")) { ind <- c(1, 3) } - if (!is.empty(input$qib_facet_row, ".") || !is.empty(input$qib_facet_col, ".")) ind <- c(ind, 4) + if (!safe_is_empty(input$qib_facet_row, ".") || !safe_is_empty(input$qib_facet_col, ".")) ind <- c(ind, 4) if (input$qib_type == "bar") ind <- c(ind, 6) checkboxGroupInput( @@ -676,7 +681,7 @@ output$ui_quickgen_basic <- renderUI({ }) qib_plot_width <- reactive({ - if (is.empty(input$qib_plot_width)) r_info[["plot_width"]] else input$qib_plot_width + if (safe_is_empty(input$qib_plot_width)) r_info[["plot_width"]] else input$qib_plot_width }) qib_plot_height <- eventReactive( @@ -686,7 +691,7 @@ qib_plot_height <- eventReactive( input$qib_plot_width }, { - if (is.empty(input$qib_plot_height)) { + if (safe_is_empty(input$qib_plot_height)) { r_info[["plot_height"]] } else { lx <- ifelse(not_available(input$qib_xvar) || isTRUE(input$qib_combx), 1, length(input$qib_xvar)) @@ -786,77 +791,49 @@ dl_qgb_tab <- function(path) { } -output$qib_chart <- renderPlot( - { - req(input$qib_type) - if (not_available(input$qib_xvar)) { - if (!input$qib_type %in% c("box", "line")) { - return( - plot( - x = 1, type = "n", - main = " ", - axes = FALSE, xlab = "", ylab = "", cex.main = .9 - ) - ) - } - } - .qib_chart() %>% - (function(x) { - if (is.empty(x) || is.character(x)) { - plot(x = 1, type = "n", main = paste0("\n", x), axes = FALSE, xlab = "", ylab = "", cex.main = .9) - } else if (length(x) > 0) { - print(x) - } - }) - }, - width = qib_plot_width, - height = qib_plot_height, - res = 96 -) +output$qib_chart <- renderPlot({ + req(input$qib_type) + p <- .qib_chart() + if (is.null(p)) return(NULL) + print(p) +}, width = qib_plot_width, height = qib_plot_height, res = 96) .qib_chart <- eventReactive(input$qib_run, { req(input$qib_type) if (input$qib_type == "scatter") req(input$qib_nrobs) - - ## need dependency on .. req(input$qib_plot_height && input$qib_plot_width) if (not_available(input$qib_xvar) && !input$qib_type %in% c("box", "line")) { - return() - } else if (input$qib_type %in% c("scatter", "line", "box", "bar", "surface") && not_available(input$qib_yvar)) { - return(i18n$t("No Y-variable provided for a plot that requires one")) - } else if (input$qib_type == "box" && !all(input$qib_xvar %in% groupable_vars())) { - return() + return(NULL) + } + if (input$qib_type %in% c("scatter", "line", "box", "bar", "surface") && not_available(input$qib_yvar)) { + return(NULL) + } + if (input$qib_type == "box" && !all(input$qib_xvar %in% groupable_vars())) { + return(NULL) } - ## waiting for comby and/or combx to be updated + ## 等待 combx / comby 更新 if (input$qib_type %in% c("dist", "density")) { - if (isTRUE(input$qib_comby)) { - return() - } - if (length(input$qib_xvar) > 1 && is.null(input$qib_combx)) { - return() - } + if (isTRUE(input$qib_comby)) return(NULL) + if (length(input$qib_xvar) > 1 && is.null(input$qib_combx)) return(NULL) } else { - if (isTRUE(input$qib_combx)) { - return() - } - if (length(input$qib_yvar) > 1 && is.null(input$qib_comby)) { - return() - } + if (isTRUE(input$qib_combx)) return(NULL) + if (length(input$qib_yvar) > 1 && is.null(input$qib_comby)) return(NULL) } - #req(!is.null(input$qib_color) || !is.null(input$qib_fill)) qibi <- qib_inputs() - qibi$dataset <- input$dataset - qibi$shiny <- TRUE - qibi$envir <- r_data - qibi$color <- "none" - qibi$fill <- "none" + qibi$dataset <- input$dataset + qibi$shiny <- TRUE + qibi$envir <- r_data + qibi$color <- "none" + qibi$fill <- "none" qibi$facet_row <- "." qibi$facet_col <- "." + withProgress(message = i18n$t("Making plot"), value = 1, { - do.call(visualize, qibi) + p <- do.call(visualize, qibi) + if (is.character(p)) return(NULL) else p }) }) @@ -875,7 +852,7 @@ observeEvent(input$qgb_store, { r_data[[dataset]] <- tmp register(dataset) updateSelectInput(session, "dataset", selected = input$dataset) - + showModal( modalDialog( title = i18n$t("Data Stored"), @@ -889,154 +866,95 @@ observeEvent(input$qgb_store, { ) }) -qgb_report <- function() { - ## get the state of the dt table - ts <- dt_state("qgb_tab") - xcmd <- "# summary(result)\ndtab(result" - if (!is.empty(input$qgb_dec, 3)) { - xcmd <- paste0(xcmd, ", dec = ", input$qgb_dec) - } - if (!is.empty(r_state$qgb_state$length, 10)) { - xcmd <- paste0(xcmd, ", pageLength = ", r_state$qgb_state$length) - } +download_handler( + id = "dl_qgb_tab", + fun = dl_qgb_tab, + fn = function() paste0(input$dataset, "_tab"), + type = "csv" +) + +download_handler( + id = "dlp_qib_chart", + fun = download_handler_plot, + fn = function() paste0(input$dataset, "_chart"), + type = "png", + caption = i18n$t("Save visualize plot"), + plot = .qib_chart, + width = qib_plot_width, + height = qib_plot_height +) + +quickgen_basic_report <- function() { + req(input$qgb_vars, input$qib_type) + + ##-------------- 表 格 部 分 -------------- + tabsort <- if (!is.null(input$qgb_state$order)) + paste0("order = ", jsonlite::toJSON(input$qgb_state$order)) else "" + tabfilt <- if (!is.null(input$qgb_search_columns)) + paste0("searchCols = ", jsonlite::toJSON(lapply(input$qgb_search_columns, function(x) list(search = x)))) else "" + xcmd <- "# quickgen table: descriptive statistics\ndtab(result" + if (!is.empty(input$qgb_dec, 3)) xcmd <- paste0(xcmd, ", dec = ", input$qgb_dec) + if (!is.empty(r_state$qgb_state$length, 10)) xcmd <- paste0(xcmd, ", pageLength = ", r_state$qgb_state$length) + if (nzchar(tabsort)) xcmd <- paste0(xcmd, ", ", tabsort) + if (nzchar(tabfilt)) xcmd <- paste0(xcmd, ", ", tabfilt) xcmd <- paste0(xcmd, ", caption = \"\") %>% render()") if (!is.empty(input$qgb_name)) { dataset <- fix_names(input$qgb_name) - if (input$qgb_name != dataset) { + if (input$qgb_name != dataset) updateTextInput(session, inputId = "qgb_name", value = dataset) - } xcmd <- paste0(xcmd, "\n", dataset, " <- result$tab\nregister(\"", dataset, "\")") } - inp_main <- clean_args(qgb_inputs(), qgb_args) - if (ts$tabsort != "") inp_main <- c(inp_main, tabsort = ts$tabsort) - if (ts$tabfilt != "") inp_main <- c(inp_main, tabfilt = ts$tabfilt) - if (is.empty(inp_main$rows)) { - inp_main$rows <- NULL - } - if (is.empty(input$qgb_tab_slice)) { - inp_main <- c(inp_main, nr = Inf) - } else { - inp_main$tabslice <- input$qgb_tab_slice - } + if (is.empty(inp_main$rows)) inp_main$rows <- NULL + if (!is.empty(input$qgb_tab_slice)) inp_main$tabslice <- input$qgb_tab_slice - inp_out <- list(clean_args(qgb_sum_inputs(), qgb_sum_args[-1])) - - update_report( - inp_main = inp_main, - fun_name = "qgb", - inp_out = inp_out, - outputs = c(), - figs = FALSE, - xcmd = xcmd - ) -} - -qib_report <- function() { - ## resetting hidden elements to default values + ##-------------- 图 形 部 分 -------------- vi <- qib_inputs() - if (input$qib_type != "dist") { - vi$bins <- qib_args$bins - } - if (input$qib_type %in% c("dist", "density")) { - vi$yvar <- qib_args$yvar - } + if (input$qib_type != "dist") vi$bins <- qib_args$bins + if (input$qib_type %in% c("dist", "density")) vi$yvar <- qib_args$yvar if (!input$qib_type %in% c("density", "scatter", "dist") || - !("loess" %in% input$qib_check || "density" %in% input$qib_axes || input$qib_type == "density")) { + !("loess" %in% input$qib_check || "density" %in% input$qib_axes || input$qib_type == "density")) vi$smooth <- qib_args$smooth - } - if (!input$qib_type %in% c("scatter", "box") && "jitter" %in% input$qib_check) { + if (!input$qib_type %in% c("scatter", "box") && "jitter" %in% input$qib_check) vi$check <- base::setdiff(vi$check, "jitter") - } if (input$qib_type != "scatter") { - vi$size <- "none" + vi$size <- "none" vi$nrobs <- NULL } else { vi$nrobs <- as_integer(vi$nrobs) } - if (!input$qib_type %in% c("scatter", "line", "box")) { - vi$color <- NULL - } - if (!input$qib_type %in% c("bar", "dist", "density", "surface")) { - vi$fill <- NULL - } + if (!input$qib_type %in% c("scatter", "line", "box")) vi$color <- NULL + if (!input$qib_type %in% c("bar", "dist", "density", "surface")) vi$fill <- NULL + if (!input$qib_type %in% c("bar", "dist", "box", "density")) vi$fillcol <- "blue" + if (!input$qib_type %in% c("dist", "density", "box", "scatter", "line")) vi$linecol <- "black" + if (!input$qib_type %in% c("box", "scatter", "line")) vi$pointcol <- "black" + if (!input$qib_type %in% c("bar", "line", "scatter")) vi$fun <- "mean" + if (safe_is_empty(input$data_rows)) vi$rows <- NULL - if (!input$qib_type %in% c("bar", "dist", "box", "density")) { - vi$fillcol <- "blue" - } - if (!input$qib_type %in% c("dist", "density", "box", "scatter", "line")) { - vi$linecol <- "black" - } - if (!input$qib_type %in% c("box", "scatter", "line")) { - vi$pointcol <- "black" - } - - if (!input$qib_type %in% c("bar", "line", "scatter")) { - vi$fun <- "mean" - } - if (is.empty(input$data_rows)) { - vi$rows <- NULL - } - - inp_main <- c(clean_args(vi, qib_args), custom = FALSE) + inp_main <- c(inp_main, clean_args(vi, qib_args), custom = FALSE) + ##-------------- 一次性写进 Report -------------- update_report( - inp_main = inp_main, - fun_name = "qib_chart", - outputs = character(0), - pre_cmd = "", - figs = TRUE, - fig.width = qib_plot_width(), + inp_main = inp_main, + fun_name = "quickgen_basic", # 统一事件名 + outputs = character(0), + pre_cmd = "", + figs = TRUE, # 需要插图 + fig.width = qib_plot_width(), fig.height = qib_plot_height() ) } -download_handler( - id = "dl_qgb_tab", - fun = dl_qgb_tab, - fn = function() paste0(input$dataset, "_tab"), - type = "csv" -) - -download_handler( - id = "dlp_qib_chart", - fun = download_handler_plot, - fn = function() paste0(input$dataset, "_chart"), - type = "png", - caption = i18n$t("Save visualize plot"), - plot = .qib_chart, - width = qib_plot_width, - height = qib_plot_height -) - - -observeEvent(input$qgb_report, { - r_info[["latest_screenshot"]] <- NULL - qgb_report() -}) - -observeEvent(input$qgb_screenshot, { - r_info[["latest_screenshot"]] <- NULL - radiant_screenshot_modal("modal_qgb_screenshot") -}) - -observeEvent(input$modal_qgb_screenshot, { - qgb_report() - removeModal() -}) - -observeEvent(input$qib_report, { +observeEvent(input$quickgen_basic_report, { r_info[["latest_screenshot"]] <- NULL - qib_report() + quickgen_basic_report() }) - -observeEvent(input$qib_screenshot, { +observeEvent(input$quickgen_basic_screenshot, { r_info[["latest_screenshot"]] <- NULL - radiant_screenshot_modal("modal_qib_screenshot") + radiant_screenshot_modal("modal_quickgen_basic_screenshot") }) - -observeEvent(input$modal_qib_screenshot, { - qib_report() +observeEvent(input$modal_quickgen_basic_screenshot, { + quickgen_basic_report() removeModal() }) diff --git a/radiant.quickgen/inst/app/tools/help/quickgen_ai.md b/radiant.quickgen/inst/app/tools/help/quickgen_ai.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..983dea5822d7e7d5fed161d45abb9016e31d809a 100644 --- a/radiant.quickgen/inst/app/tools/help/quickgen_ai.md +++ b/radiant.quickgen/inst/app/tools/help/quickgen_ai.md @@ -0,0 +1,27 @@ +> 大模型生成描述性统计 + +## 使用方法 + +以下是 `大模型生成描述性统计`的使用方法。 + +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 diff --git a/set_path.R b/set_path.R index 4f80e1b24b451b28d9e9ce4cdee496394d8f9970..391503e65d0f383dca7eff838d5b4b6630ea5832 100644 --- a/set_path.R +++ b/set_path.R @@ -1,4 +1,3 @@ -# 创建文件 /home/wuzekai/radiant/set_path.R cat <<'EOF' | sudo tee /home/wuzekai/radiant/set_path.R options(radiant.launch_dir = "/data") options(radiant.project_dir = "/data")