PK
Y·JÖDÉÿŠ Š package.json{
"version": "1.0.1",
"author": {"name":"Microsoft","email":"pbicvsupport@microsoft.com"},
"resources": [
{
"resourceId": "rId0",
"sourceType": 5,
"file": "resources/PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2.pbiviz.json"
}
],
"visual": {"name":"PowerBI-visuals-assorules","displayName":"Association rules","guid":"PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2","visualClassName":"Visual","version":"1.0.1","description":"Association rules are if/then statements that help uncover relationships between seemingly unrelated data. The rules are automatically detected and visualized. This visual supports several methods for association rules visualization such as table, graph or parallel coordinates plot. You can control the algorithm parameters and the visual attributes to suit your needs.
Service prerequisites: R-powered custom visual is used in service seamlessly
Desktop prerequisites: To run R scripts in Power BI Desktop, you must separately install R on your local computer.
You can download and install R for free from the Revolution Open download page or the CRAN Repository
R package dependencies(auto-installed): nloptr, seriation, gtools, caTools, lmtest, arules, arulesViz, grDevices, gridExtra, grid, methods
Supports R versions: R 3.3.1, R 3.3.0, MRO 3.3.1, MRO 3.3.0, MRO 3.2.2
","supportUrl":"http://community.powerbi.com/","gitHubUrl":"https://github.com/microsoft/PowerBI-visuals-assorules"},
"metadata": {
"pbivizjson": {
"resourceId": "rId0"
}
}
}
PK
Y·J
resources/PK
Y·JDŠ^u¢ u¢ A resources/PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2.pbiviz.json{"visual":{"name":"PowerBI-visuals-assorules","displayName":"Association rules","guid":"PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2","visualClassName":"Visual","version":"1.0.1","description":"Association rules are if/then statements that help uncover relationships between seemingly unrelated data. The rules are automatically detected and visualized. This visual supports several methods for association rules visualization such as table, graph or parallel coordinates plot. You can control the algorithm parameters and the visual attributes to suit your needs.
Service prerequisites: R-powered custom visual is used in service seamlessly
Desktop prerequisites: To run R scripts in Power BI Desktop, you must separately install R on your local computer.
You can download and install R for free from the Revolution Open download page or the CRAN Repository
R package dependencies(auto-installed): nloptr, seriation, gtools, caTools, lmtest, arules, arulesViz, grDevices, gridExtra, grid, methods
Supports R versions: R 3.3.1, R 3.3.0, MRO 3.3.1, MRO 3.3.0, MRO 3.2.2
","supportUrl":"http://community.powerbi.com/","gitHubUrl":"https://github.com/microsoft/PowerBI-visuals-assorules"},"apiVersion":"1.2.0","author":{"name":"Microsoft","email":"pbicvsupport@microsoft.com"},"assets":{"icon":"assets/icon.png"},"externalJS":[],"style":"style/visual.less","capabilities":{"dataRoles":[{"displayName":"Unique ID","description":"May be used optionally to prevent two identical rows from being counted as one","kind":"GroupingOrMeasure","name":"ID"},{"displayName":"LHS","description":"Items for Left Hand Side (LHS) of IF LHS THEN RHS (binary or categorical variable)","kind":"Grouping","name":"LHS"},{"displayName":"RHS","description":"Items for Right Hand Side (LHS) of IF LHS THEN RHS (binary or categorical variable) ","kind":"Grouping","name":"RHS"},{"displayName":"BOTH","description":"Items allowed in LHS or RHS (binary or cagegorical variable)","kind":"Grouping","name":"BOTH"}],"dataViewMappings":[{"conditions":[{"ID":{"max":1},"LHS":{"max":100},"RHS":{"max":100},"BOTH":{"max":100}}],"scriptResult":{"dataInput":{"table":{"rows":{"select":[{"for":{"in":"ID"}},{"for":{"in":"LHS"}},{"for":{"in":"RHS"}},{"for":{"in":"BOTH"}}],"dataReductionAlgorithm":{"top":{}}}}},"script":{"scriptProviderDefault":"R","scriptOutputType":"png","source":{"objectName":"rcv_script","propertyName":"source"},"provider":{"objectName":"rcv_script","propertyName":"provider"},"scriptSourceDefault":"# Copyright (c) Microsoft Corporation. All rights reserved.\r\n\r\n# Third Party Programs. This software enables you to obtain software applications from other sources. \r\n# Those applications are offered and distributed by third parties under their own license terms.\r\n# Microsoft is not developing, distributing or licensing those applications to you, but instead, \r\n# as a convenience, enables you to use this software to obtain those applications directly from \r\n# the application providers.\r\n# By using the software, you acknowledge and agree that you are obtaining the applications directly\r\n# from the third party providers and under separate license terms, and that it is your responsibility to locate, \r\n# understand and comply with those license terms.\r\n# Microsoft grants you no license rights for third-party software or applications that is obtained using this software.\r\n\r\n##PBI_R_VISUAL: VIZGAL_ASSORULES Analyzing transaction data and visualize discovered assosiation rules \r\n# Based on arules package, supports several types of visualization (graph, table, parrallel coordinates plot)\r\n# INPUT: \r\n# The input dataset should include at least one ID-key column (unique values per row)\r\n# At least one column used for Left Hand Side (LHS) items, at least one column for Right Hand Side (RHS) items\r\n# In current implementation by default only the last column is used for RHS, but it can be changed via parameters settings \r\n# EXAMPLES:\r\n# for R environment\r\n# data(Titanic)# and repeat ech row by frequency\r\n# Titanic1 = as.data.frame(Titanic)\r\n# Titanic2 <- data.frame(Titanic1[rep(c(1:nrow(Titanic1)), Titanic1$Freq), ])\r\n# Titanic2$Freq = NULL\r\n# dataset = cbind(ID = 1:nrow(Titanic2), Titanic2)\r\n# source(\"visGal_assoRules.R\") #create graphics\r\n#\r\n# WARNINGS: Time consuming for large datasets\r\n#\r\n# CREATION DATE: 04/01/2016\r\n#\r\n# LAST UPDATE: 04/08/2016\r\n#\r\n# VERSION: 0.0.1\r\n#\r\n# R VERSION TESTED: 3.2.2\r\n# \r\n# AUTHOR: B. Efraty (boefraty@microsoft.com)\r\n#\r\n# REFERENCES: https://cran.r-project.org/web/packages/arules/arules.pdf\r\n# https://en.wikipedia.org/wiki/Association_rule_learning\r\n\r\nfileRda = \"C:/Users/boefraty/projects/PBI/R/tempData.Rda\"\r\nif(file.exists(dirname(fileRda)))\r\n{\r\n if(Sys.getenv(\"RSTUDIO\")!=\"\")\r\n load(file= fileRda)\r\n else\r\n save(list = ls(all.names = TRUE), file=fileRda)\r\n}\r\n\r\n\r\n#PBI_EXAMPLE_DATASET for debugging purposes \r\nif(!exists(\"dataset\") && !exists(\"LHS\") && !exists(\"RHS\") && !exists(\"BOTH\") && !exists(\"ID\"))\r\n{\r\n data(Titanic)# and repeat ech row by frequency\r\n Titanic1 = as.data.frame(Titanic)\r\n Titanic2 <- data.frame(Titanic1[rep(c(1:nrow(Titanic1)), Titanic1$Freq), ])\r\n Titanic2$Freq = NULL\r\n dataset = cbind(ID = 1:nrow(Titanic2), Titanic2)\r\n\r\n}\r\n\r\nwaitForData = FALSE # if waitForData == TRUE show empty plot \r\nif(!exists(\"dataset\") && !(exists(\"BOTH\") || (exists(\"LHS\") && exists(\"RHS\"))) )\r\n waitForData = TRUE\r\n\r\n\r\n\r\n############ User Parameters #########\r\n\r\nif(exists(\"settings_thresholds_params_show\") && settings_thresholds_params_show == FALSE)\r\n rm(list= ls(pattern = \"settings_thresholds_params_\"))\r\nif(exists(\"settings_rules_params_show\") && settings_rules_params_show == FALSE)\r\n rm(list= ls(pattern = \"settings_rules_params_\"))\r\nif(exists(\"settings3_show\") && settings3_show == FALSE)\r\n rm(list= ls(pattern = \"settings3_\"))\r\nif(exists(\"settings_viz_params_show\") && settings_viz_params_show == FALSE)\r\n rm(list= ls(pattern = \"settings_viz_params_\"))\r\nif(exists(\"settings_additional_params_show\") && settings_additional_params_show == FALSE)\r\n rm(list= ls(pattern = \"settings_additional_params_\"))\r\n\r\n##PBI_PARAM: Should warnings text be displayed?\r\n#Type:logical, Default:TRUE, Range:NA, PossibleValues:NA, Remarks: NA\r\nshowWarnings = TRUE \r\nif(exists(\"settings_additional_params_showWarnings\"))\r\n showWarnings = settings_additional_params_showWarnings\r\n\r\n##PBI_PARAM: a numeric value for the minimal support of an item set\r\n#Type: numeric, Default:0.01, Range:[0, 1], PossibleValues:NA, Remarks: NA\r\nthreshSupport = 0.01\r\nif(exists(\"settings_thresholds_params_threshSupport\"))\r\n threshSupport = as.numeric(settings_thresholds_params_threshSupport)\r\n\r\nthreshSupport = min(1,max(threshSupport,0))\r\n\r\n\r\n##PBI_PARAM: minimum acceptable confidence for rule \r\n#Type: numeric, Default:0.6, Range:[0, 1], PossibleValues:NA, Remarks: NA\r\nthreshConfidence = 0.6\r\nif(exists(\"settings_thresholds_params_threshConfidence\"))\r\n threshConfidence = as.numeric(settings_thresholds_params_threshConfidence)\r\n\r\nthreshConfidence = min(1,max(threshConfidence,0))\r\n\r\n##PBI_PARAM: minimum acceptable lift measure for rule \r\n#Type: numeric, Default:1.1, Range:[0, 10], PossibleValues:NA, Remarks: values larger than 1 are recommended\r\nthreshLift = 1.1\r\nif(exists(\"settings_thresholds_params_threshLift\"))\r\n threshLift = as.numeric(settings_thresholds_params_threshLift)\r\n\r\nthreshLift = min(1000000,max(threshLift,0))\r\n\r\n\r\n##PBI_PARAM: an integer value for the minimal number of items per item set\r\n#Type: numeric, Default:2, Range:[1, 10], PossibleValues:NA, Remarks: NA\r\nminRuleLength = 2\r\nif(exists(\"settings_thresholds_params_minRuleLength\"))\r\n minRuleLength = as.numeric(settings_thresholds_params_minRuleLength)\r\n\r\nminRuleLength = min(12,max(minRuleLength,2))\r\n\r\n\r\n##PBI_PARAM: an integer value for the maximal number of items per item set\r\n#Type: numeric, Default:8, Range:[1, 20], PossibleValues:NA, Remarks: Should be larger than minRuleLength, have gross impact on running time\r\nmaxRuleLength = 8\r\nif(exists(\"settings_thresholds_params_maxRuleLength\"))\r\n maxRuleLength = as.numeric(settings_thresholds_params_maxRuleLength)\r\n\r\nmaxRuleLength = min(12,max(minRuleLength,maxRuleLength))\r\n\r\n\r\nshowFrom = 1\r\nif(exists(\"settings_rules_params_showFrom\"))\r\n showFrom = as.numeric(settings_rules_params_showFrom)\r\n\r\n##PBI_PARAM: an integer value for the maximal number of output rules\r\n#Type: integer, Default:20, Range:[1, 100], PossibleValues:NA, Remarks: Large number of rules are less aesthetically pleasing for visual \r\nmaxRules = 5\r\nif(exists(\"settings_rules_params_showTo\"))\r\n maxRules = as.numeric(settings_rules_params_showTo)\r\n\r\nshowTo = maxRules\r\nshowTo = max(showTo,showFrom)# can not be smaller\r\n\r\n\r\n##PBI_PARAM: sort and select the final set of rules by selected measure\r\n#Type: string , Default:\"lift\", Range:NA, PossibleValues:\"lift\", \"support\", \"confidence\", Remarks: NA\r\nsortRulesBy = \"lift\" \r\nif(exists(\"settings_rules_params_sortBy\"))\r\n sortRulesBy = settings_rules_params_sortBy\r\n\r\n##PBI_PARAM: visualization method\r\n# Type: string , Default:\"graph\", Range:NA, PossibleValues:\"paracoord\" \"table\", \"graph\", \"scatter\"\r\n# Remarks: Some methods are less convenient for few rules\r\nvisualisationMethod = \"graph\" \r\nif(exists(\"settings_viz_params_visualisationMethod\"))\r\n visualisationMethod = settings_viz_params_visualisationMethod#c(\"graph\",\"paracoord\" ,\"table\", \"scatter\")[settings_visualisationMethod]\r\n\r\n##PBI_PARAM: minimum number of rules per subplot used if visualisationMethod = \"graph\" \r\n#Type: integer , Default:2, Range:[1, 100], PossibleValues:NA, Remarks: NA\r\nrulesPerGraphPlate = 1\r\nif(exists(\"settings_viz_params_rulesPerPlate\"))\r\n{\r\n rulesPerGraphPlate = as.numeric(settings_viz_params_rulesPerPlate)\r\n if(is.na(rulesPerGraphPlate))\r\n rulesPerGraphPlate = 1\r\n}\r\n###############Library Declarations###############\r\n\r\nlibraryRequireInstall = function(packageName, ...)\r\n{\r\n if(!require(packageName, character.only = TRUE)) \r\n warning(paste(\"*** The package: '\", packageName, \"' was not installed ***\",sep=\"\"))\r\n}\r\n\r\n\r\nlibraryRequireInstall(\"arules\")\r\nlibraryRequireInstall(\"arulesViz\")\r\nlibraryRequireInstall(\"grDevices\")\r\nlibraryRequireInstall(\"gridExtra\")\r\nlibraryRequireInstall(\"grid\")\r\nlibraryRequireInstall(\"methods\")\r\n\r\n###############Internal parameters definitions#################\r\n\r\n##PBI_PARAM: color of edges for LHS items for visualisationMethod = \"graph\" \r\n#Type: color , Default:\"green\", Range:NA, PossibleValues:\"red\", \"green\", \"blue\", \"cyan\", Remarks: see colors {grDevices} command in R\r\nedgeColLHS = \"green\"\r\nif(exists(\"settings_viz_params_edgeColLHS\"))\r\n edgeColLHS = settings_viz_params_edgeColLHS\r\n\r\n##PBI_PARAM: color of edges for RHS items for visualisationMethod = \"graph\" \r\n#Type: color , Default:\"orange\", Range:NA, PossibleValues:\"red\", \"green\", \"blue\", \"cyan\", Remarks: see colors {grDevices} command in R\r\nedgeColRHS = \"orange\"\r\nif(exists(\"settings_viz_params_edgeColRHS\"))\r\n edgeColRHS = settings_viz_params_edgeColRHS\r\n\r\n##PBI_PARAM: font size of labels for visualisationMethod = \"graph\" \r\n#Type: numeric , Default:1, Range:[0, 5], PossibleValues:NA, Remarks: NA\r\nfontSizeGraph = 1\r\nif(exists(\"settings_viz_params_textSize\"))\r\n fontSizeGraph = settings_viz_params_textSize/10\r\n\r\n##PBI_PARAM: colors used if visualisationMethod = \"paracoord\" are scaled from gray to green accirding to one of the measures \r\n#Type: string , Default:\"lift\", Range:NA, PossibleValues:\"lift\", \"support\", \"confidence\", Remarks: NA\r\nparCoordColorBy = \"lift\"\r\nif(exists(\"settings_viz_params_colorBy\"))\r\n parCoordColorBy = settings_viz_params_colorBy\r\n\r\n##PBI_PARAM: filter redundant rules by selected measure\r\n#Type: string , Default:\"lift\", Range:NA, PossibleValues:\"lift\", \"confidence\", Remarks: rule is redundant if it is less predictive than a more general rule \r\nfilterRedundantBy = \"lift\"\r\n\r\n##PBI_PARAM: maximum acceptable support for rule \r\n#Type: numeric, Default:1, Range:[0, 1], PossibleValues:NA, Remarks: NA\r\nupperThreshSupport = 1\r\nif(exists(\"settings3_threshSupport\"))\r\n upperThreshSupport = as.numeric(settings3_threshSupport)\r\n\r\n##PBI_PARAM: maximum acceptable confidence for rule \r\n#Type: numeric, Default:1, Range:[0, 1], PossibleValues:NA, Remarks: NA\r\nupperThreshConfidence = 1\r\nif(exists(\"settings3_threshConfidence\"))\r\n upperThreshConfidence = as.numeric(settings3_threshConfidence)\r\n\r\n##PBI_PARAM: maximum acceptable confidence for rule \r\n#Type: positive numeric, Default:Inf, Range:[0, Inf], PossibleValues:NA, Remarks: NA\r\nupperThreshLift = Inf\r\nif(exists(\"settings3_threshLift\"))\r\n upperThreshLift = as.numeric(settings3_threshLift)\r\n\r\n##PBI_PARAM: array of integer indexes for columns used in left hand side of the rule (LHS)\r\n#Type: array of integers or NA, Default:NA, Range:NA, PossibleValues:NA, Remarks: If NA is used all the columns except for the right-most are used \r\nif(!exists(\"columnsLHS\"))\r\n columnsLHS = NA\r\n\r\n##PBI_PARAM: array of integer indexes for columns used in right hand side of the rule (RHS)\r\n#Type: array of integers or NA, Default:NA, Range:NA, PossibleValues:NA, Remarks: If NA is used, the right-most column is selected \r\nif(!exists(\"columnsRHS\"))\r\n columnsRHS = NA\r\n\r\n##PBI_PARAM: array of integer indexes for columns used both in RHS and LHS\r\n#Type: array of integers or NA or NULL, Default:NA, Range:NA, PossibleValues:NA, Remarks: If NA is used, no columns are selected\r\nif(!exists(\"columnsBoth\"))\r\ncolumnsBoth = NA\r\n\r\n##PBI_PARAM: minimum number of transactions (rows) to run \r\n#Type: integer , Default:10, Range:[10, 100], PossibleValues:NA, Remarks: NA\r\nminTransactions = 10\r\n\r\n###############Internal functions definitions#################\r\n\r\n#remove corrupt rows, change nominal variables to factors, remove variable columns\r\n# attempt to replace numeric column with few unique values to factor \r\nprepareData = function(data, onlyColumns = FALSE) \r\n{\r\n if(onlyColumns == FALSE)\r\n data <- data[complete.cases(data), ] #remove incomplete rows\r\n columns2remove <- NULL\r\n nc <- ncol(data)\r\n nr <- nrow(data)\r\n for (c1 in 1:nc)\r\n {\r\n #nominal to factor\r\n if(is.character(data[, c1]))\r\n {\r\n data[, c1] <- as.factor(data[, c1])\r\n }else{\r\n #few unique to factor\r\n uLen = length(unique(data[, c1]))\r\n if(uLen1) \r\n {\r\n data[, c1] <- as.factor(data[, c1])\r\n }else{# to remove\r\n columns2remove = c(columns2remove, c1)\r\n }\r\n }\r\n }\r\n if(!is.null(columns2remove))\r\n data = data[, -columns2remove]\r\n return(as.data.frame(data))\r\n}\r\n\r\n#predict columns for LHS by default (all but last)\r\ncolumnsForLHS <- function(data) return(seq(1, length.out = ncol(data)-1))\r\n\r\n#predict columns for RHS by default (only last)\r\ncolumnsForRHS <- function(data) return(ncol(data))\r\n\r\n#predict columns for both RHS and LHS by default (NULL)\r\ncolumnsForBoth <- function(data) return(NULL)\r\n\r\n#convert transaction data to appearance list\r\nConstructAppearanceList <- function(varLHS = NULL, varRHS = NULL, varBoth = NULL, transData)\r\n{\r\n mapLabels2Variables = transData@itemInfo\r\n iii = mapLabels2Variables$variables %in% varLHS\r\n lhs = mapLabels2Variables$labels[iii]\r\n \r\n iii = mapLabels2Variables$variables %in% varRHS\r\n rhs = mapLabels2Variables$labels[iii]\r\n \r\n iii = mapLabels2Variables$variables %in% varBoth\r\n both = mapLabels2Variables$labels[iii]\r\n \r\n appearance = list(lhs = lhs, rhs = rhs, both = both, default = 'none')\r\n}\r\n\r\n#partition rules into subplots\r\ngetGridPartition <- function(numRules, rulesPerGraphPlate)\r\n{\r\n numPlates = max(1, floor(numRules/rulesPerGraphPlate))\r\n numCols <- round(sqrt(numPlates))\r\n numRows <- max(1, floor(numPlates/numCols))\r\n numPlates = numRows*numCols\r\n #partition all rules into plates\r\n rulesPerGraphPlate = floor(numRules/numPlates)\r\n partit <- rep(rulesPerGraphPlate, numPlates)\r\n #last subplot takes the rest \r\n partit[numPlates] = partit[numPlates]+numRules-sum(partit)\r\n return(list(partit = partit, numCols = numCols, numRows = numRows))\r\n}\r\n\r\n#scale colors from gray to green by values (of measure), small = > gray, large = > green\r\nscaleColors <- function(values, col1 = c(0.5, 0.5, 0.5), col2 = c(0, 1, 0))\r\n{\r\n NV = length(values)\r\n values = (values-min(values)+1e-10)/(max(values)-min(values)+1e-10)\r\n colo <- function(a) rgb(t((col1*(1-a)+col2*(a))))\r\n return(sapply(values, colo))\r\n}\r\n\r\n#clear redandant rules \r\ncleanRedundant <- function(rules, maxRules2process = 3e+06, measure = \"lift\", meaningfulDig = 4)\r\n{\r\n rules@quality = round(rules@quality, digits = meaningfulDig)\r\n rules <- sort(rules, by = \"lift\")\r\n \r\n if(length(rules)<3)\r\n return(rules)\r\n \r\n if(length(rules)>maxRules2process)\r\n rules <- rules[1:maxRules2process]\r\n \r\n r <- is.redundant(rules, measure = measure)\r\n if(is.redundant(rules[1], measure = measure))\r\n r<-!r\r\n rules <- rules[!r]#fast but not accurate\r\n \r\n \r\n if(length(rules)<3)\r\n return(rules)\r\n \r\n subsetMat <- is.subset(rules)\r\n \r\n \r\n subsetMat[lower.tri(subsetMat, diag = T)] <- FALSE\r\n \r\n if(length(subsetMat)<=3)\r\n return(rules)\r\n \r\n \r\n \r\n redundant <- which(colSums(subsetMat, na.rm = T) >= 1)\r\n toRemove = NULL\r\n for (r1 in redundant)\r\n for (r2 in which(subsetMat[, r1]))\r\n if((rules@quality[measure])[r2, 1] == (rules@quality[measure])[r1, 1])\r\n toRemove = c(toRemove, r1)\r\n \r\n if(!is.null(toRemove))\r\n rules = rules[-toRemove]\r\n \r\n return(rules)\r\n}\r\n###############Upfront input correctness validations (where possible)#################\r\npbiWarning <- NULL\r\n\r\n\r\nif(waitForData==FALSE &&(exists(\"LHS\")||exists(\"RHS\") || exists(\"BOTH\")))\r\n{\r\n if(!exists(\"RHS\"))\r\n RHS = data.frame()\r\n if(!exists(\"LHS\"))\r\n LHS = data.frame()\r\n if(!exists(\"BOTH\"))\r\n BOTH = data.frame()\r\n \r\n #exclude duplicates\r\n namesInLHSnRHSnotBOTH= setdiff(intersect(names(LHS),names(RHS)),names(BOTH)) # copy to BOTH\r\n if(length(namesInLHSnRHSnotBOTH)>0)\r\n {\r\n nbo = c(names(BOTH),namesInLHSnRHSnotBOTH)\r\n BOTH = cbind(BOTH,LHS[,namesInLHSnRHSnotBOTH])\r\n names(BOTH) = nbo\r\n }\r\n namesInLHSnBOTH= intersect(names(LHS),names(BOTH)) #exclude from LHS\r\n if(length(namesInLHSnBOTH)>0)\r\n LHS=as.data.frame(LHS[,setdiff(names(LHS),namesInLHSnBOTH)])\r\n \r\n namesInRHSnBOTH= intersect(names(RHS),names(BOTH)) #exclude from LHS\r\n if(length(namesInRHSnBOTH)>0)\r\n RHS=as.data.frame(RHS[,setdiff(names(RHS),namesInRHSnBOTH)])\r\n \r\n\r\n columnsLHS = columnsRHS = columnsBoth = NULL\r\n \r\n NR = max(nrow(LHS),nrow(RHS),nrow(BOTH))\r\n if(!ncol(RHS))\r\n RHS = data.frame(row.names = 1:NR)\r\n if(!ncol(LHS))\r\n LHS = data.frame(row.names = 1:NR)\r\n if(!ncol(BOTH))\r\n BOTH = data.frame(row.names = 1:NR)\r\n \r\n \r\n if(ncol(LHS))\r\n {\r\n LHS = prepareData(LHS, onlyColumns = TRUE)\r\n columnsLHS <- seq(1,length.out = ncol(LHS))\r\n }\r\n inLeft = length(columnsLHS)\r\n \r\n if(ncol(BOTH))\r\n {\r\n BOTH = prepareData(BOTH, onlyColumns = TRUE)\r\n columnsBoth <- seq(inLeft+1,length.out = ncol(BOTH))\r\n }\r\n inBoth = length(columnsBoth)\r\n \r\n if(ncol(RHS))\r\n {\r\n RHS = prepareData(RHS, onlyColumns = TRUE)\r\n columnsRHS <- seq(inLeft+inBoth+1,length.out = ncol(RHS))\r\n }\r\n inRHS = length(columnsRHS)\r\n if(nrow(LHS) > 1)\r\n dataset = cbind(LHS,BOTH,RHS)\r\n\r\n}\r\n\r\n\r\nif(exists(\"dataset\") && !is.null(dataset))\r\n{\r\n dataset = prepareData(dataset)\r\n} else {\r\n dataset = NULL\r\n}\r\nif(is.null(dataset) || ncol(dataset)<2)\r\n columnsLHS = columnsRHS = columnsBoth = NULL;\r\n\r\n#LHS, RHS\r\nif(!is.null(columnsLHS) && is.na(columnsLHS))\r\n columnsLHS <- columnsForLHS(dataset)\r\n\r\nif(!is.null(columnsRHS) &&is.na(columnsRHS))\r\n columnsRHS <- columnsForRHS(dataset)\r\n\r\nif(!is.null(columnsBoth) &&is.na(columnsBoth))\r\n columnsBoth <- columnsForBoth(dataset)\r\n\r\n#check if LHS and RHS non empty\r\nif(length(columnsLHS)+length(columnsBoth)<1 || length(columnsRHS)+length(columnsBoth)<1 || waitForData == TRUE )\r\n{\r\n visualisationMethod = \"empty\"\r\n pbiWarning <- paste(pbiWarning, \"Both LHS and RHS should not be empty\", sep = \"\\n\")\r\n\r\n#check if minRuleLength<= maxRuleLength\r\n}else if(minRuleLength>maxRuleLength )\r\n{\r\n visualisationMethod = \"empty\"\r\n pbiWarning <- paste(pbiWarning, \"maxRuleLength needs to be >= minRuleLength\", sep = \"\\n\")\r\n} else if(nrow(dataset)threshLift]\r\n \r\n #take care of redandancy\r\n rules <- cleanRedundant(rules, measure = filterRedundantBy)\r\n \r\n rules <- sort(rules, by = sortRulesBy)\r\n if(length(rules)>maxRules)\r\n rules = rules[1:maxRules]\r\n}\r\n\r\n#cut showFrom to showTo\r\nif(length(rules)>=showFrom)\r\n{\r\n rules = rules[max(1,showFrom):min(showTo,length(rules))]\r\n}else{\r\n rules = NULL\r\n}\r\n\r\n\r\n\r\nif(length(rules) == 0)\r\n{\r\n visualisationMethod = \"empty\"\r\n pbiWarning <- paste(pbiWarning, \"No rules generated, for current set of thresholds\", sep = \"\\n\")\r\n}\r\n\r\n#Visualizing Association Rules\r\nif(visualisationMethod == \"graph\") # graph \r\n{\r\n gp = getGridPartition(length(rules), rulesPerGraphPlate)\r\n \r\n \r\n par(oma=0.25*c(1,1,1,1),mar=0.5*c(1,1,1,1), mfrow = c(gp$numRows, gp$numCols), xpd = TRUE)\r\n # unfortunatly: mar and xpd are overwrited\r\n \r\n for (p in 1:length(gp$partit))\r\n {\r\n s = sum(gp$partit[seq(1, length.out = p-1)])+1\r\n e = s+gp$partit[p]-1\r\n print(s:e)\r\n \r\n numEdgesRHS = sum(as(rules[s:e]@rhs, \"matrix\"))\r\n numEdgesLHS = sum(as(rules[s:e]@lhs, \"matrix\"))\r\n edge.color = c(rep(edgeColLHS, numEdgesLHS), rep(edgeColRHS, numEdgesRHS))\r\n \r\n plot(rules[s:e], method = \"graph\", \r\n control = list(type = \"items\", alpha = 1, measureLabels = FALSE, \r\n cex = fontSizeGraph, precision = 1, arrowSize = 0.5, main = \"\", layoutParams\t = list(xpd = T)), edge.color = edge.color, margin = -0.01, frame = FALSE)\r\n \r\n }\r\n}\r\n\r\nif(visualisationMethod == \"table\") # table \r\n{\r\n qualityMetrics <- rules@quality\r\n lhs <- rules@lhs@data\r\n rhs <- rules@rhs@data\r\n \r\n NR <- nrow(qualityMetrics)\r\n NR = min(NR, maxRules)\r\n \r\n rutable <- data.frame(From = rep(NA, NR), To = rep(NA, NR), qualityMetrics[1:NR, ])\r\n lhsColNames = colnames(rules@lhs)\r\n rhsColNames = colnames(rules@rhs)\r\n \r\n for (r in (1:NR))\r\n {\r\n if(any(lhs[, r]))\r\n rutable$From[r] <- paste(lhsColNames[lhs[, r]], collapse = \"\\n\")\r\n if(any(rhs[, r]))\r\n rutable$To[r] <- paste(rhsColNames[rhs[, r]], collapse = \"\\n\")\r\n }\r\n \r\n names(rutable) = toupper(names(rutable))\r\n \r\n tt <- ttheme_minimal(\r\n core = list(bg_params = list(fill = blues9[1:4], col = \"gray\"), \r\n fg_params = list(fontface = 3, cex = fontSizeGraph)), \r\n colhead = list(fg_params = list(col = \"orange\", fontface = 4L,cex = fontSizeGraph*1.1)), \r\n rowhead = list(fg_params = list(col = \"white\", fontface = 3L)))\r\n \r\n plot.new()\r\n grid.table(rutable, theme = tt)\r\n title(main = \"\")\r\n}\r\n\r\n\r\nif(visualisationMethod == \"paracoord\")#parcoord \r\n{\r\n reorder = (length(rules)<42 && length(rules)>3) #reorder only if it is fast (few rules)\r\n if(length(rules)>0)\r\n {\r\n plot(rules, method = \"paracoord\", control = list( reorder = reorder, main = \"\", col = scaleColors(rules@quality[[parCoordColorBy]])))\r\n }else{\r\n visualisationMethod = \"empty\"\r\n pbiWarning <- paste(pbiWarning, \"Paracoord method works only with two or more rules\", sep = \"\\n\")\r\n }\r\n \r\n}\r\n\r\nif(visualisationMethod == \"scatter\") #scatter (for Debug and Exploration) \r\n plot(rules, control = list(cex = fontSizeGraph))# scatter \r\n\r\nif(visualisationMethod == \"empty\") #scatter (for Debug and Exploration) \r\n{\r\n plot.new()\r\n title(sub = pbiWarning, col.sub = \"gray50\")\r\n}\r\n\r\nremove(\"dataset\")"}}}],"objects":{"rcv_script":{"properties":{"provider":{"type":{"text":true}},"source":{"type":{"scripting":{"source":true}}}}},"settings_thresholds_params":{"displayName":"Thresholds","description":"Thresholds for association rules mining.","properties":{"show":{"type":{"bool":true}},"minRuleLength":{"displayName":"Min Rule Length","description":"For Left Hand Side (LHS) and Right Hand Side (RHS) of a rule","type":{"enumeration":[{"displayName":"2","value":"2"},{"displayName":"3","value":"3"},{"displayName":"4","value":"4"},{"displayName":"5","value":"5"},{"displayName":"6","value":"6"},{"displayName":"7","value":"7"},{"displayName":"8","value":"8"},{"displayName":"9","value":"9"},{"displayName":"10","value":"10"}]}},"maxRuleLength":{"displayName":"Max Rule Length","description":"For Left Hand Side (LHS) and Right Hand Side (RHS) of a rule","type":{"enumeration":[{"displayName":"2","value":"2"},{"displayName":"3","value":"3"},{"displayName":"4","value":"4"},{"displayName":"5","value":"5"},{"displayName":"6","value":"6"},{"displayName":"7","value":"7"},{"displayName":"8","value":"8"},{"displayName":"9","value":"9"},{"displayName":"10","value":"10"}]}},"threshSupport":{"displayName":"Support >","description":"Threshold for how often the rule is applicable for the current dataset (greater than 0 is significant, larger is better)","type":{"numeric":true}},"threshConfidence":{"displayName":"Confidence >","description":"Threshold for how frequently RHS items appear in transactions that contain LHS (greater than .5 is significant)","type":{"numeric":true}},"threshLift":{"displayName":"Lift >","description":"Threshold for the ratio between the rule's confidence and the expected confidence (greater than 1 is significant)","type":{"numeric":true}}}},"settings_rules_params":{"displayName":"Rules selection","description":"Determines how resulting rules are sorted","properties":{"show":{"type":{"bool":true}},"sortBy":{"displayName":"Sort by ","description":"Sort by an attribute","type":{"enumeration":[{"displayName":"support","value":"support"},{"displayName":"confidence","value":"confidence"},{"displayName":"lift","value":"lift"}]}},"showFrom":{"displayName":"Show from rule #","description":"Fewer rules generate less clutter","type":{"numeric":true}},"showTo":{"displayName":" ... to rule # ","description":"Fewer rules generate less clutter","type":{"numeric":true}}}},"settings_viz_params":{"displayName":"Rules visualization","description":"Select plot type and parameters","properties":{"show":{"type":{"bool":true}},"visualisationMethod":{"displayName":"Visualization","type":{"enumeration":[{"displayName":"graph","value":"graph"},{"displayName":"paracoord","value":"paracoord"},{"displayName":"table","value":"table"},{"displayName":"scatter","value":"scatter"}]}},"rulesPerPlate":{"displayName":"Rules per plate","description":"Fewer rules per plate generates more graph components","type":{"enumeration":[{"displayName":"1","value":"1"},{"displayName":"2","value":"2"},{"displayName":"3","value":"3"},{"displayName":"4","value":"4"},{"displayName":"5","value":"5"},{"displayName":"6","value":"6"},{"displayName":"7","value":"7"},{"displayName":"Unlimited","value":"1000"}]}},"textSize":{"displayName":"Font size","type":{"numeric":true}},"edgeColLHS":{"displayName":"Color of LHS","description":"Edge color","type":{"fill":{"solid":{"color":true}}}},"edgeColRHS":{"displayName":"Color of RHS","description":"Edge color","type":{"fill":{"solid":{"color":true}}}},"colorBy":{"displayName":"Color by","description":"Color visual based on a rules' attributes","type":{"enumeration":[{"displayName":"support","value":"support"},{"displayName":"confidence","value":"confidence"},{"displayName":"lift","value":"lift"}]}}}},"settings_additional_params":{"displayName":"Additional parameters","properties":{"show":{"type":{"bool":true}},"showWarnings":{"displayName":"Show warnings","type":{"bool":true}}}}},"suppressDefaultTitle":true},"dependencies":{"cranPackages":[{"name":"nloptr","displayName":"nloptr: R interface to NLopt","url":"https://cran.r-project.org/web/packages/nloptr/index.html"},{"name":"TSP","displayName":"TSP: Traveling Salesperson Problem (TSP)","url":"https://cran.r-project.org/web/packages/TSP/index.html"},{"name":"scales","displayName":"scales: Scale Functions for Visualization","url":"https://cran.r-project.org/web/packages/scales/index.html"},{"name":"fpc","displayName":"fpc: Flexible Procedures for Clustering","url":"https://cran.r-project.org/web/packages/fpc/index.html"},{"name":"gplots","displayName":"gplots: Various R Programming Tools for Plotting Data","url":"https://cran.r-project.org/web/packages/gplots/index.html"},{"name":"ggplot2","displayName":"ggplot2: An Implementation of the Grammar of Graphics","url":"https://cran.r-project.org/web/packages/ggplot2/index.html"},{"name":"gtools","displayName":"gtools: Various R Programming Tools","url":"https://cran.r-project.org/web/packages/gtools/index.html"},{"name":"caTools","displayName":"caTools: Tools: moving window statistics etc","url":"https://cran.r-project.org/web/packages/caTools/index.html"},{"name":"lmtest","displayName":"lmtest: Testing Linear Regression Models","url":"https://cran.r-project.org/web/packages/lmtest/index.html"},{"name":"arules","displayName":"arules: Mining Association Rules","url":"https://cran.r-project.org/web/packages/arules/index.html"},{"name":"gridExtra","displayName":"gridExtra: Miscellaneous Functions for Grid Graphics","url":"https://cran.r-project.org/web/packages/gridExtra/index.html"},{"name":"seriation","displayName":"seriation: Infrastructure for Ordering Objects Using Seriation","url":"https://cran.r-project.org/web/packages/seriation/index.html"},{"name":"dplyr","displayName":"dplyr: A Grammar of Data Manipulation","url":"https://cran.r-project.org/web/packages/dplyr/index.html"},{"name":"NMF","displayName":"NMF: Algorithmsfor Nonnegative Matrix Factorization","url":"https://cran.r-project.org/web/packages/NMF/index.html"},{"name":"igraph","displayName":"igraph: Network Analysis and Visualization","url":"https://cran.r-project.org/web/packages/igraph/index.html"},{"name":"arulesViz","displayName":"arulesViz: Visualizing Association Rules","url":"https://cran.r-project.org/web/packages/arulesViz/index.html"}]},"stringResources":{},"content":{"js":"var powerbi;!function(t){!function(t){!function(t){!function(t){function s(t,s,e,i){if(t){var a=t[s];if(a){var r=a[e];if(void 0!==r)return r}}return i}function e(t,s,e,i,a,r){if(t){var n=t[s];if(n){var o=n[e];if(or)return r;if(void 0!==o)return o}}return i}function i(t,s,e,i,a,r){if(t){var n=t[s];if(n){var o=n[e];if(void 0!==o)return o>r?r:oe?e:t}function o(t,s,e){return Number(t)e?e.toString():t}function h(t,s){return\"graph\"==t&&\"N/A\"==s?\"1\":\"graph\"!=t?\"N/A\":s}function l(t,s){return\"paracoord\"==t&&\"N/A\"==s?\"lift\":\"paracoord\"!=t?\"N/A\":s}function _(t,s,e,i,a){var r=t.objects;if(r){var n=r[s];if(n){var o=n[e];if(o){var h=o[i];if(void 0!==h)return h}}}return a}t.getValue=s,t.getValueMinMax=e,t.getValueNumberMinMax=i,t.ifStringReturnString=a,t.ifStringReturnStringClustersMethod=r,t.inMinMax=n,t.inMinMaxString=o,t.inVisMethodAndRulesPerPlate=h,t.inVisMethodAndColorBy=l,t.getCategoricalObjectValue=_}(t.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2||(t.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2={}))}(t.visual||(t.visual={}))}(t.extensibility||(t.extensibility={}))}(powerbi||(powerbi={}));var powerbi;!function(t){!function(t){!function(t){!function(t){var s=function(){function s(t){this.imageDiv=document.createElement(\"div\"),this.imageDiv.className=\"rcv_autoScaleImageContainer\",t.element.appendChild(this.imageDiv),this.imageElement=document.createElement(\"img\"),this.imageElement.className=\"rcv_autoScaleImage\",this.imageDiv.appendChild(this.imageElement),this.settings_thresholds_params={show:!1,minRuleLength:\"2\",maxRuleLength:\"8\",threshSupport:.01,threshConfidence:.6,threshLift:1.1},this.settings_rules_params={show:!1,sortBy:\"lift\",showFrom:1,showTo:5},this.settings_viz_params={show:!1,visualisationMethod:\"graph\",rulesPerPlate:\"1\",textSize:10,edgeColLHS:\"green\",edgeColRHS:\"orange\",colorBy:\"lift\"},this.settings_additional_params={show:!1,showWarnings:!1}}return s.prototype.update=function(s){var e=s.dataViews;if(e&&0!==e.length){var i=e[0];if(i&&i.metadata){this.settings_thresholds_params={show:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"show\",!1),maxRuleLength:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"maxRuleLength\",\"8\"),minRuleLength:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"minRuleLength\",\"2\"),threshSupport:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"threshSupport\",.01),threshConfidence:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"threshConfidence\",.6),threshLift:t.getValue(i.metadata.objects,\"settings_thresholds_params\",\"threshLift\",1.1)},this.settings_rules_params={show:t.getValue(i.metadata.objects,\"settings_rules_params\",\"show\",!1),sortBy:t.getValue(i.metadata.objects,\"settings_rules_params\",\"sortBy\",\"lift\"),showFrom:t.getValue(i.metadata.objects,\"settings_rules_params\",\"showFrom\",1),showTo:t.getValue(i.metadata.objects,\"settings_rules_params\",\"showTo\",5)},this.settings_viz_params={show:t.getValue(i.metadata.objects,\"settings_viz_params\",\"show\",!1),visualisationMethod:t.getValue(i.metadata.objects,\"settings_viz_params\",\"visualisationMethod\",\"graph\"),rulesPerPlate:t.getValue(i.metadata.objects,\"settings_viz_params\",\"rulesPerPlate\",\"1\"),textSize:t.getValue(i.metadata.objects,\"settings_viz_params\",\"textSize\",10),edgeColLHS:t.getValue(i.metadata.objects,\"settings_viz_params\",\"edgeColLHS\",\"green\"),edgeColRHS:t.getValue(i.metadata.objects,\"settings_viz_params\",\"edgeColRHS\",\"orange\"),colorBy:t.getValue(i.metadata.objects,\"settings_viz_params\",\"colorBy\",\"lift\")},this.settings_additional_params={show:t.getValue(i.metadata.objects,\"settings_additional_params\",\"show\",!1),showWarnings:t.getValue(i.metadata.objects,\"settings_additional_params\",\"showWarnings\",!1)};var a=null;i.scriptResult&&i.scriptResult.payloadBase64&&(a=\"data:image/png;base64,\"+i.scriptResult.payloadBase64),this.imageElement.src=a||null,this.onResizing(s.viewport)}}},s.prototype.onResizing=function(t){this.imageDiv.style.height=t.height+\"px\",this.imageDiv.style.width=t.width+\"px\"},s.prototype.enumerateObjectInstances=function(s){var e=s.objectName,i=[];switch(e){case\"settings_thresholds_params\":i.push({objectName:e,properties:{show:this.settings_thresholds_params.show,minRuleLength:t.inMinMaxString(this.settings_thresholds_params.minRuleLength,2,10),maxRuleLength:t.inMinMaxString(this.settings_thresholds_params.maxRuleLength,Number(this.settings_thresholds_params.minRuleLength),10),threshSupport:t.inMinMax(this.settings_thresholds_params.threshSupport,0,1),threshConfidence:t.inMinMax(this.settings_thresholds_params.threshConfidence,0,1),threshLift:t.inMinMax(this.settings_thresholds_params.threshLift,0,1e6)},selector:null});break;case\"settings_rules_params\":i.push({objectName:e,properties:{show:this.settings_rules_params.show,sortBy:this.settings_rules_params.sortBy,showFrom:this.settings_rules_params.showFrom,showTo:t.inMinMax(this.settings_rules_params.showTo,this.settings_rules_params.showFrom,100)},selector:null});break;case\"settings_viz_params\":\"graph\"==this.settings_viz_params.visualisationMethod?i.push({objectName:e,properties:{show:this.settings_viz_params.show,visualisationMethod:this.settings_viz_params.visualisationMethod,rulesPerPlate:t.inVisMethodAndRulesPerPlate(this.settings_viz_params.visualisationMethod,this.settings_viz_params.rulesPerPlate),textSize:this.settings_viz_params.textSize,edgeColLHS:this.settings_viz_params.edgeColLHS,edgeColRHS:this.settings_viz_params.edgeColRHS},selector:null}):\"paracoord\"==this.settings_viz_params.visualisationMethod?i.push({objectName:e,properties:{show:this.settings_viz_params.show,visualisationMethod:this.settings_viz_params.visualisationMethod,colorBy:t.inVisMethodAndColorBy(this.settings_viz_params.visualisationMethod,this.settings_viz_params.colorBy)},selector:null}):\"table\"==this.settings_viz_params.visualisationMethod?i.push({objectName:e,properties:{show:this.settings_viz_params.show,visualisationMethod:this.settings_viz_params.visualisationMethod,textSize:this.settings_viz_params.textSize},selector:null}):\"scatter\"==this.settings_viz_params.visualisationMethod&&i.push({objectName:e,properties:{show:this.settings_viz_params.show,visualisationMethod:this.settings_viz_params.visualisationMethod,textSize:this.settings_viz_params.textSize},selector:null});break;case\"settings_additional_params\":i.push({objectName:e,properties:{show:this.settings_additional_params.show,showWarnings:this.settings_additional_params.showWarnings},selector:null})}return i},s}();t.Visual=s}(t.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2||(t.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2={}))}(t.visual||(t.visual={}))}(t.extensibility||(t.extensibility={}))}(powerbi||(powerbi={}));var powerbi;!function(t){!function(s){!function(s){s.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2={name:\"PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2\",displayName:\"Association rules\",class:\"Visual\",version:\"1.0.1\",apiVersion:\"1.2.0\",create:function(s){return new t.extensibility.visual.PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2.Visual(s)},custom:!0}}(s.plugins||(s.plugins={}))}(t.visuals||(t.visuals={}))}(powerbi||(powerbi={}));","css":".visual-PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2 .rcv_autoScaleImageContainer{position:relative}.visual-PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2 .rcv_autoScaleImageContainer .rcv_autoScaleImage{max-width:100%;max-height:100%;position:absolute;top:50%;left:50%;transform:translateY(-50%) translateX(-50%);-webkit-transform:translateY(-50%) translateX(-50%)}","iconBase64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUZJREFUeNpiYBjsgBGZ8yTRWgFIJQDxByDeIDP/6AOyDQQaBjJoPpIcyFBHoKEXSDGQBYndjyYnALLg0qXLE4H0BT09XRSDvVt2geQNQHJba9w+oLgQ6DoHILUfm43vCmcgu3gDEB8E4gOVm56vhxoIEleEGcoEVYzLW+hhCApjhZuvfgZADYP5xADFy8Bw+gB05QQgswDNgEKoCx4AvfwAzcvxMC8jOwg9lkERYw9if7f0efjdwmcC0KAPuCIAaKgB0KvERRowMhyA+DwQG5ASy0y4JIAuOwD1LsjQArISNjZXIsU+KIYT8QUBQQOhhoIMdOD+cYeB79vFB9CYXgCKMFGHhg9EexkJJIIMAmJYsmGAZs/1JIUhUlg+ALkOC3B4faBBgRwX4gMC5Bq4AYvYBWAYXiDXwEZoRDAgZdVEhiEJAAIMAM4pdFEWp5pMAAAAAElFTkSuQmCC"}}PK
Y·JÖDÉÿŠ Š package.jsonPK
Y·J
´ resources/PK
Y·JDŠ^u¢ u¢ A Ü resources/PBI_CV_3EEA6E26_A754_4ECA_BE51_C93859851FB2.pbiviz.jsonPK á °ª