├── .DS_Store ├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── R ├── data.R ├── linneman.R ├── markovify.R └── markovifyR-package.R ├── README.Rmd ├── README.md ├── data └── linneman_lessons.rda ├── docs ├── authors.html ├── docsearch.css ├── docsearch.js ├── link.svg ├── pkgdown.css ├── pkgdown.js └── pkgdown.yml ├── inst └── examples │ └── bap_example.R ├── man ├── combine_markov_models.Rd ├── export_markov_model.Rd ├── generate_corpus.Rd ├── generate_markovify_model.Rd ├── generate_parsed_sentences.Rd ├── generate_start_words.Rd ├── get_data_linneman_lessons.Rd ├── install_markovify.Rd ├── linneman_lessons.Rd ├── markovifyR.Rd └── markovify_text.Rd └── markovifyR.Rproj /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abresler/markovifyR/187ffa9cb6a1c9c0d7a7a7c40af9cfe0819f5af5/.DS_Store -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | tests/ -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: markovifyR 2 | Type: Package 3 | Title: R wrapper for the Markovify Python module 4 | Version: 0.102 5 | Date: 2017-09-18 6 | Author: Alex Bresler (abresler@@asbcllc.com) 7 | Maintainer: Alex Bresler 8 | Description: R wrapper for the 'Markovify' () library. This package allows for easy and text generation using hidden markov models. 9 | URL: https://github.com/abresler/markovifyR 10 | BugReports: https://github.com/abresler/markovifyR/issues 11 | License: AGPL 12 | Suggests: 13 | testthat 14 | Depends: 15 | R (>= 3.2.0) 16 | Imports: 17 | reticulate, 18 | glue, 19 | dplyr, 20 | purrr, 21 | stringr, 22 | tibble, 23 | furrr, 24 | rlang, 25 | future 26 | LazyData: true 27 | RoxygenNote: 7.2.3 28 | Encoding: UTF-8 29 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(combine_markov_models) 4 | export(export_markov_model) 5 | export(generate_corpus) 6 | export(generate_markovify_model) 7 | export(generate_parsed_sentences) 8 | export(generate_start_words) 9 | export(get_data_linneman_lessons) 10 | export(install_markovify) 11 | export(markovify_text) 12 | import(dplyr) 13 | import(furrr) 14 | import(future) 15 | import(purrr) 16 | import(reticulate) 17 | import(stringr) 18 | import(tibble) 19 | importFrom(glue,glue) 20 | importFrom(rlang,UQ) 21 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' Peter Linneman's life lessons 2 | #' 3 | #' List of Peter Linnemans life lessons 4 | #' 5 | #' @format Data frame with columns 6 | #' \describe{ 7 | #' \item{idLesson}{Lesson Number} 8 | #' \item{textLesson}{Lesson Text} 9 | #' ... 10 | #' } 11 | #' @source \url{https://asbcllc.com/reflections/peter_linneman/} 12 | "linneman_lessons" -------------------------------------------------------------------------------- /R/linneman.R: -------------------------------------------------------------------------------- 1 | #' Newest Linneman lessons 2 | #' 3 | #' @return a \code{tibble} 4 | #' @export 5 | #' @references \url{asbcllc.com/reflections/peter_linneman/} 6 | #' @examples 7 | #' get_data_linneman_lessons() 8 | get_data_linneman_lessons <- 9 | function() { 10 | lessons <- 11 | "https://asbcllc.com/reflections/peter_linneman/linnemen_lessons.txt" %>% 12 | readLines() 13 | 14 | tibble(textLesson = lessons) %>% 15 | mutate(idLesson = 1:n()) %>% 16 | select(idLesson, everything()) 17 | } 18 | -------------------------------------------------------------------------------- /R/markovify.R: -------------------------------------------------------------------------------- 1 | #' Install Markovify Python module 2 | #' 3 | #' @return invisible 4 | #' @export 5 | #' 6 | #' @examples 7 | #' \dontrun{ 8 | #' install_markovify() 9 | #' } 10 | install_markovify <- 11 | function() { 12 | system("pip install markovify") 13 | } 14 | 15 | #' Generate Markovify model 16 | #' 17 | #' Generate a markov model for a 18 | #' given input text and set of model 19 | #' parameters 20 | #' 21 | #' @param input_text a \code{vector} of text 22 | #' @param max_overlap_total maximum overlap total 23 | #' default is \code{15} 24 | #' @param max_overlap_ratio maximum overlap ratio 25 | #' \code{default is .7} 26 | #' @param tries number over times to try to generate a sentence 27 | #' @param markov_state_size markov state to use 28 | #' \code{default} is 2 29 | #' 30 | #' @return a markov model in Python object form 31 | #' @export 32 | #' @examples 33 | #' \dontrun{ 34 | #' library(dplyr) 35 | #' library(markovifyR) 36 | #' data("linneman_lessons") 37 | #' df <- linneman_lessons 38 | #' lessons <- 39 | #' df %>% 40 | #' pull(textLesson) 41 | #' markov_model <- 42 | #' generate_markovify_model( 43 | #' input_text = lessons, 44 | #' markov_state_size = 3L, 45 | #' max_overlap_total = 15, 46 | #' max_overlap_ratio = .8 47 | #' ) 48 | #' markov_model 49 | #' } 50 | generate_markovify_model <- 51 | function(input_text, 52 | markov_state_size = 2, 53 | max_overlap_total = 15, 54 | max_overlap_ratio = .70, 55 | tries = 100) { 56 | 57 | if (max_overlap_ratio > 1) { 58 | stop("Overlap ratio can only be between 0 and 1") 59 | } 60 | 61 | markov_state_size <- 62 | as.integer(markov_state_size) 63 | 64 | mk <- 65 | reticulate::import("markovify") 66 | 67 | tries <- as.integer(tries) 68 | 69 | max_overlap_total <- as.integer(max_overlap_total) 70 | max_overlap_ratio <- max_overlap_ratio 71 | 72 | mk$text$DEFAULT_TRIES <- 73 | tries 74 | mk$text$DEFAULT_MAX_OVERLAP_TOTAL <- 75 | max_overlap_total 76 | mk$text$DEFAULT_MAX_OVERLAP_RATIO <- 77 | max_overlap_ratio 78 | markov_model <- 79 | mk$Text(input_text = input_text, state_size = markov_state_size) 80 | 81 | markov_model 82 | } 83 | 84 | generate_short_sentence <- 85 | function(markov_model, 86 | output_column_name = "textLinnemanBot", 87 | maximum_sentence_length = 1200, 88 | count = 50, 89 | tries = 100, 90 | only_distinct = TRUE, 91 | return_message = TRUE) { 92 | 93 | df_text <- 94 | 1:count %>% 95 | future_map_dfr(function(x) { 96 | text_output <- 97 | markov_model$make_short_sentence(max_chars = maximum_sentence_length, tries = as.integer(tries)) 98 | ## if no result try again 99 | if (text_output %>% length() == 0) { 100 | text_output <- 101 | markov_model$make_short_sentence(max_chars = maximum_sentence_length) 102 | } 103 | 104 | if (text_output %>% length() == 0) { 105 | text_output <- NA 106 | } 107 | ## return data frame 108 | tibble(idRow = x, UQ(output_column_name) := text_output) 109 | }) 110 | 111 | if (only_distinct) { 112 | df_text <- 113 | df_text %>% 114 | select(-idRow) %>% 115 | distinct() %>% 116 | mutate(idRow = 1:n()) %>% 117 | select(idRow, everything()) 118 | } 119 | df_text 120 | 121 | if (return_message) { 122 | 1:nrow(df_text) %>% 123 | walk(function(x) { 124 | text_output <- 125 | df_text %>% slice(x) %>% select(2) %>% pull(UQ(output_column_name)) 126 | glue::glue("\n\n{output_column_name}: {text_output}\n\n") %>% cat(fill = T) 127 | }) 128 | 129 | } 130 | df_text 131 | } 132 | 133 | generate_sentence <- 134 | function(markov_model, 135 | output_column_name = "textLinnemanBot", 136 | count = 50, 137 | tries = 100, 138 | only_distinct = TRUE, 139 | return_message = TRUE) { 140 | df_text <- 141 | 1:count %>% 142 | future_map_dfr(function(x) { 143 | text_output <- 144 | markov_model$make_sentence() 145 | ## if no result try again 146 | if (text_output %>% length() == 0) { 147 | text_output <- 148 | markov_model$make_sentence(tries = as.integer(tries)) 149 | } 150 | 151 | if (text_output %>% length() == 0) { 152 | text_output <- NA 153 | } 154 | ## return data frame 155 | tibble(idRow = x, UQ(output_column_name) := text_output) 156 | }) 157 | 158 | if (only_distinct) { 159 | df_text <- 160 | df_text %>% 161 | select(-idRow) %>% 162 | distinct() %>% 163 | mutate(idRow = 1:n()) %>% 164 | select(idRow, everything()) 165 | } 166 | 167 | if (return_message) { 168 | 1:nrow(df_text) %>% 169 | walk(function(x) { 170 | text_output <- 171 | df_text %>% slice(x) %>% select(2) %>% pull(UQ(output_column_name)) 172 | glue::glue("{crayon::blue(output_column_name)}: {crayon::white(text_output)}") %>% cat(fill = T) 173 | }) 174 | 175 | } 176 | 177 | df_text 178 | } 179 | 180 | 181 | 182 | #' Combine markov models 183 | #' 184 | #' Builds a combined 185 | #' markov model 186 | #' 187 | #' @param model_a first model 188 | #' @param model_b second model 189 | #' @param weights numeric vector of 2 weights 190 | #' defaults are \code{c(1, 1.5)} 191 | #' 192 | #' @return 193 | #' @export 194 | #' @examples 195 | combine_markov_models <- 196 | function(model_a, model_b, weights = c(1, 1.5)) { 197 | mk <- reticulate::import("markovify") 198 | 199 | model <- 200 | mk$combine(models = c(model_a, model_b), weights = weights) 201 | model 202 | } 203 | 204 | #' Generate a corpus from a 205 | #' markov model 206 | #' 207 | #' @param markov_model markov model object 208 | #' @param input_text vector of input text 209 | #' 210 | #' @return 211 | #' @export 212 | #' @examples 213 | generate_corpus <- 214 | function(markov_model, input_text) { 215 | corpus <- markov_model$generate_corpus(text = input_text) 216 | corpus 217 | } 218 | 219 | #' Generate parsed sentences 220 | #' 221 | #' This function returns the parsed input 222 | #' text in sentence form 223 | #' 224 | #' @param markov_model 225 | #' 226 | #' @return a \code{list} 227 | #' @export 228 | #' 229 | #' @examples 230 | generate_parsed_sentences <- 231 | function(markov_model) { 232 | markov_model$parsed_sentences 233 | } 234 | 235 | generate_sentence_starting_with <- 236 | function(markov_model, start_word) { 237 | sentence <- markov_model$make_sentence_with_start(beginning = start_word) 238 | 239 | if (!'sentence' %>% exists()) { 240 | stop(glue::glue("Cannot start sentenc with {start_word}")) 241 | } 242 | sentence 243 | } 244 | 245 | generate_sentences_starting_with <- 246 | function(markov_model, 247 | start_word, 248 | output_column_name = "textLinnemanBot", 249 | count = 50, 250 | tries = 100, 251 | only_distinct = TRUE, 252 | return_message = TRUE) { 253 | generate_sentence_starting_with_safe <- 254 | purrr::possibly(generate_sentence_starting_with, tibble) 255 | 256 | df_text <- 257 | 1:count %>% 258 | future_map_dfr(function(x){ 259 | text_output <- 260 | generate_sentence_starting_with_safe(markov_model = markov_model, start_word = start_word) 261 | if (text_output %>% purrr::is_null()) { 262 | return(invisible()) 263 | } 264 | tibble(idRow = x, wordStart = start_word ,UQ(output_column_name) := text_output) 265 | }) 266 | 267 | if (only_distinct) { 268 | df_text <- 269 | df_text %>% 270 | select(-idRow) %>% 271 | distinct() %>% 272 | mutate(idRow = 1:n()) %>% 273 | select(idRow, everything()) 274 | } 275 | 276 | if (return_message) { 277 | 1:nrow(df_text) %>% 278 | walk(function(x) { 279 | text_output <- 280 | df_text %>% slice(x) %>% select(3) %>% pull(UQ(output_column_name)) 281 | glue::glue("{output_column_name}: {text_output}") %>% cat(fill = T) 282 | }) 283 | 284 | } 285 | 286 | df_text 287 | } 288 | 289 | generate_sentences_starting_with_words <- 290 | function(markov_model, 291 | start_words = c("If", "You"), 292 | output_column_name = "textLinnemanBot", 293 | count = 50, 294 | tries = 100, 295 | only_distinct = TRUE, 296 | return_message = TRUE) { 297 | 298 | generate_sentences_starting_with_safe <- 299 | purrr::possibly(generate_sentences_starting_with, tibble()) 300 | 301 | all_data <- 302 | start_words %>% 303 | future_map_dfr(function(x) { 304 | generate_sentences_starting_with_safe( 305 | markov_model = markov_model, 306 | start_word = x, 307 | output_column_name = output_column_name, 308 | count = count, 309 | tries = tries, 310 | only_distinct = only_distinct, 311 | return_message = return_message 312 | ) 313 | }) 314 | 315 | all_data 316 | } 317 | 318 | #' Generate start words 319 | #' 320 | #' @param markov_model markov model mobject 321 | #' @param include_cumulative_distance if \code{TRUE} returns 322 | #' cumulative distance of the words 323 | #' 324 | #' @return a \code{tibble} objects 325 | #' @export 326 | #' @examples 327 | generate_start_words <- 328 | function(markov_model, include_cumulative_distance = TRUE) { 329 | start <- markov_model$chain$begin_choices 330 | 331 | df <- 332 | seq_along(start) %>% 333 | future_map_dfr(function(x){ 334 | word <- start[[x]] 335 | tibble(idSentence = x, wordStart = word) 336 | }) 337 | 338 | if (include_cumulative_distance) { 339 | df <- 340 | df %>% 341 | mutate(distanceCumulative = markov_model$chain$begin_cumdist) 342 | } 343 | df 344 | } 345 | 346 | #' Markovify text 347 | #' 348 | #' Produces text output from 349 | #' a markov model based pn user specified 350 | #' parameters 351 | #' 352 | #' @param markov_model a markov model produced from \code{generate_markovify_model} 353 | #' @param start_words a markov model produced with a list of start word terms 354 | #' @param maximum_sentence_length the maximum length of the sentence 355 | #' if \code{NULL} model will produce a random sentence of any length. 356 | #' @param output_column_name name of the 357 | #' @param count count of the number of sentences, default \code{50} 358 | #' @param tries count of the number of tries to produce a coherent sentence 359 | #' @param only_distinct if \code{TRUE} returns only distinct text 360 | #' @param return_message if \code{TRUE} returns a message 361 | #' 362 | #' @return a \code{tibble} 363 | #' @export 364 | #' @examples 365 | #' \dontrun{ 366 | #' library(dplyr) 367 | #' library(markovifyR) 368 | #' data("linneman_lessons") 369 | #' df <- linneman_lessons 370 | #' lessons <- df %>% pull(textLesson) 371 | #' markov_model <- 372 | #' generate_markovify_model( 373 | #' input_text = lessons, 374 | #' markov_state_size = 2L, 375 | #' max_overlap_total = 15, 376 | #' max_overlap_ratio = .8) 377 | #' 378 | #'markovify_text( 379 | #'markov_model = markov_model, 380 | #'count = 100, 381 | #'maximum_sentence_length = 1500L, 382 | #'output_column_name = 'linnemanBotText', 383 | #'tries = 100, 384 | #'only_distinct = TRUE, 385 | #'return_message = TRUE 386 | #') 387 | #' } 388 | markovify_text <- 389 | function(markov_model, 390 | maximum_sentence_length = NULL, 391 | start_words = NULL, 392 | output_column_name = "columnName", 393 | count = 50, 394 | tries = 100, 395 | only_distinct = TRUE, 396 | return_message = TRUE) { 397 | 398 | if (!start_words %>% purrr::is_null()) { 399 | data <- 400 | generate_sentences_starting_with_words(markov_model = markov_model, 401 | start_words = start_words, 402 | output_column_name = output_column_name, 403 | count = count, 404 | tries = tries, 405 | only_distinct = only_distinct, 406 | return_message = return_message) 407 | 408 | return(data) 409 | } 410 | 411 | if (maximum_sentence_length %>% purrr::is_null()) { 412 | data <- 413 | generate_sentence(markov_model = markov_model, 414 | output_column_name = output_column_name, 415 | count = count, 416 | tries = tries, 417 | only_distinct = only_distinct, 418 | return_message = return_message) 419 | return(data) 420 | } 421 | 422 | data <- 423 | generate_short_sentence( 424 | markov_model = markov_model, 425 | maximum_sentence_length = maximum_sentence_length, 426 | output_column_name = output_column_name, 427 | count = count, 428 | tries = tries, 429 | only_distinct = only_distinct, 430 | return_message = return_message 431 | ) 432 | 433 | data 434 | 435 | } 436 | 437 | #' Export Markov Model 438 | #' 439 | #' @param markov_model a markov model object 440 | #' @param format \itemize{ 441 | #' \item json - returns a json object 442 | #' \item dict - returns dictionary object 443 | #' } 444 | #' @return a json or dictionary object 445 | #' @export 446 | #' @import purrr reticulate stringr tibble dplyr 447 | #' @examples 448 | export_markov_model <- 449 | function(markov_model, format = "json"){ 450 | if (!format %>% stringr::str_to_lower() == "json"){ 451 | output <- markov_model$to_dict() 452 | } 453 | output <- 454 | markov_model$to_json() 455 | output 456 | } 457 | -------------------------------------------------------------------------------- /R/markovifyR-package.R: -------------------------------------------------------------------------------- 1 | #' Markovify wrapper for R 2 | #' 3 | #' @name markovifyR 4 | #' @docType package 5 | #' @author Alex Bresler (abresler@@asbcllc.com) 6 | #' @import dplyr purrr stringr reticulate tibble furrr future 7 | #' @importFrom glue glue 8 | #' @importFrom rlang UQ 9 | 10 | NULL -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "MarkovifyR" 3 | output: github_document 4 | --- 5 | 6 | 7 | `markovifyR` : R wrapper for Markovify 8 | 9 | Ref: 10 | 11 | >_"Markovify is a simple, extensible Markov chain generator. Right now, its main use is for building Markov models of large corpora of text, and generating random sentences from that."_ 12 | 13 | This package requires Python and markovify to be installed. 14 | 15 | To install markovify in R you can run: 16 | 17 | ```{r eval = F} 18 | system("pip install markovify") 19 | ``` 20 | 21 | The following functions are implemented: 22 | 23 | - `generate_markovify_model:` Generates a markov model 24 | - `markovify_text`: Generates text from a markov model 25 | - `generate_sentence_starting_with`: Generates text, if possible, with your specified start word 26 | - `generate_start_words`: Produces a data frame with the starting words for each input sentence 27 | - 28 | 29 | ### Installation 30 | 31 | ```{r eval=FALSE} 32 | devtools::install_github("abresler/markovifyR") 33 | ``` 34 | 35 | ```{r message=FALSE, warning=FALSE, error=FALSE} 36 | options(width=120) 37 | ``` 38 | 39 | ### Usage 40 | 41 | ```{r message=FALSE, warning=FALSE, error=FALSE} 42 | library(markovifyR) 43 | library(dplyr) 44 | ``` 45 | 46 | ### Generate New Peter Linneman "Life Lessons"" 47 | 48 | Here we are going to showcase how to use the package to create new [Life Lessons](asbcllc.com/reflections/peter_linneman/) from my favorite professor from college Peter Linneman. 49 | 50 | #### Step 1 -- Build the Corpus 51 | 52 | ```{r} 53 | data("linneman_lessons") 54 | 55 | lessons <- 56 | linneman_lessons %>% 57 | pull(textLesson) 58 | 59 | lessons %>% str() 60 | ``` 61 | 62 | #### Step 2 -- Build the Model 63 | 64 | ```{r} 65 | markov_model <- 66 | generate_markovify_model( 67 | input_text = lessons, 68 | markov_state_size = 2L, 69 | max_overlap_total = 25, 70 | max_overlap_ratio = .85 71 | ) 72 | 73 | ``` 74 | 75 | 76 | ### Step 3 -- Generate the Text 77 | ```{r} 78 | markovify_text( 79 | markov_model = markov_model, 80 | maximum_sentence_length = NULL, 81 | output_column_name = 'textLinnemanBot', 82 | count = 25, 83 | tries = 100, 84 | only_distinct = TRUE, 85 | return_message = TRUE 86 | ) 87 | 88 | ``` 89 | 90 | #### Step 4 -- Other Features 91 | 92 | Generate random sentence starting with. 93 | 94 | ```{r} 95 | markovify_text( 96 | markov_model = markov_model, 97 | maximum_sentence_length = NULL, 98 | start_words = c("The", "You", "Life"), 99 | output_column_name = 'textLinnemanBot', 100 | count = 25, 101 | tries = 100, 102 | only_distinct = TRUE, 103 | return_message = TRUE 104 | ) 105 | ``` 106 | 107 | Look at corpus start-words 108 | 109 | 110 | ```{r} 111 | generate_start_words(markov_model = markov_model) 112 | ``` 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MarkovifyR 2 | ================ 3 | 4 | `markovifyR` : R wrapper for Markovify 5 | 6 | Ref: 7 | 8 | > *"Markovify is a simple, extensible Markov chain generator. Right now, its main use is for building Markov models of large corpora of text, and generating random sentences from that."* 9 | 10 | This package requires Python and markovify to be installed. 11 | 12 | To install markovify in R you can run: 13 | 14 | ``` r 15 | system("pip install markovify") 16 | ``` 17 | 18 | The following functions are implemented: 19 | 20 | - `generate_markovify_model:` Generates a markov model 21 | - `markovify_text`: Generates text from a markov model 22 | - `generate_sentence_starting_with`: Generates text, if possible, with your specified start word 23 | - `generate_start_words`: Produces a data frame with the starting words for each input sentence 24 | - 25 | 26 | ### Installation 27 | 28 | ``` r 29 | devtools::install_github("abresler/markovifyR") 30 | ``` 31 | 32 | ``` r 33 | options(width=120) 34 | ``` 35 | 36 | ### Usage 37 | 38 | ``` r 39 | library(markovifyR) 40 | library(dplyr) 41 | ``` 42 | 43 | ### Generate New Peter Linneman "Life Lessons"" 44 | 45 | Here we are going to showcase how to use the package to create new [Life Lessons](asbcllc.com/reflections/peter_linneman/) from my favorite professor from college Peter Linneman. 46 | 47 | #### Step 1 -- Build the Corpus 48 | 49 | ``` r 50 | data("linneman_lessons") 51 | 52 | lessons <- 53 | linneman_lessons %>% 54 | pull(textLesson) 55 | 56 | lessons %>% str() 57 | ``` 58 | 59 | ## chr [1:101] "You always have time for what is important to you" ... 60 | 61 | #### Step 2 -- Build the Model 62 | 63 | ``` r 64 | markov_model <- 65 | generate_markovify_model( 66 | input_text = lessons, 67 | markov_state_size = 2L, 68 | max_overlap_total = 25, 69 | max_overlap_ratio = .85 70 | ) 71 | ``` 72 | 73 | ### Step 3 -- Generate the Text 74 | 75 | ``` r 76 | markovify_text( 77 | markov_model = markov_model, 78 | maximum_sentence_length = NULL, 79 | output_column_name = 'textLinnemanBot', 80 | count = 25, 81 | tries = 100, 82 | only_distinct = TRUE, 83 | return_message = TRUE 84 | ) 85 | ``` 86 | 87 | ## textLinnemanBot: “What is the bet?” is the bet?” is the outcome of hard work every day; not a eureka experience 88 | 89 | ## textLinnemanBot: Your job in life that can’t be fixed, so don’t go crazy when things break 90 | 91 | ## textLinnemanBot: Putting profits before power will generally result in a life of power 92 | 93 | ## textLinnemanBot: Members of the people you love 94 | 95 | ## textLinnemanBot: Generosity is cheap over the long term, as you will never realize it was your fault; then ask how you feel about them 96 | 97 | ## textLinnemanBot: Life isn’t fair, so don’t go crazy when things are unfair 98 | 99 | ## textLinnemanBot: “What is the right thing simply because it is what it is what it is the right thing simply because it is the bet?” is the outcome of hard work every day; not a eureka experience 100 | 101 | ## textLinnemanBot: Just when you are doing something, and do it Then it is learned as you wrinkle 102 | 103 | ## textLinnemanBot: Let the people you love 104 | 105 | ## textLinnemanBot: Genius is the critical question 106 | 107 | ## textLinnemanBot: Genius is the bet?” is the bet?” is the critical question 108 | 109 | ## textLinnemanBot: Enjoy what you do not respect yourself, why should anyone else respect you 110 | 111 | ## textLinnemanBot: In the battle between fear and greed, greed wins about 80% of the people you love 112 | 113 | ## textLinnemanBot: Assume it was your fault; then ask how you feel about them 114 | 115 | ## textLinnemanBot: Stick to what you do not feel so special 116 | 117 | ## textLinnemanBot: People are the problem 118 | 119 | ## textLinnemanBot: To interview well, think of yourself like a stripper; you need to be me and us; most people want it to be mean and they will view it as a very nasty statement 120 | 121 | ## textLinnemanBot: Why ever do less than the sadness of their life rather than the sadness of their life rather than the best you that you can be 122 | 123 | ## textLinnemanBot: Take ownership of your death, so do not love yourself, there is no reason others should love you 124 | 125 | ## textLinnemanBot: Stick to what you do not love yourself, there is no reason others should love you 126 | 127 | ## textLinnemanBot: There are very few things in life that can’t be fixed, so don’t take it personally if yours are strange and difficult; so don’t take it personally if yours are strange and difficult 128 | 129 | ## textLinnemanBot: Find out who you are If people don’t like it, that’s their problem 130 | 131 | ## textLinnemanBot: There are just a humble school teacher” 132 | 133 | ## textLinnemanBot: Life isn’t fair, so don’t take it personally if yours are strange and difficult 134 | 135 | ## textLinnemanBot: The machine is rarely the problem; the people you love 136 | 137 | ## # A tibble: 25 x 2 138 | ## idRow textLinnemanBot 139 | ## 140 | ## 1 1 "“What is the bet?” is the bet?” is the outcome of hard work every day; not a eureka experience" 141 | ## 2 2 "Your job in life that can’t be fixed, so don’t go crazy when things break" 142 | ## 3 3 "Putting profits before power will generally result in a life of power" 143 | ## 4 4 "Members of the people you love" 144 | ## 5 5 "Generosity is cheap over the long term, as you will never realize it was your fault; then ask how you feel a… 145 | ## 6 6 "Life isn’t fair, so don’t go crazy when things are unfair" 146 | ## 7 7 "“What is the right thing simply because it is what it is what it is the right thing simply because it is the… 147 | ## 8 8 "Just when you are doing something, and do it Then it is learned as you wrinkle" 148 | ## 9 9 "Let the people you love" 149 | ## 10 10 "Genius is the critical question" 150 | ## # ... with 15 more rows 151 | 152 | #### Step 4 -- Other Features 153 | 154 | Generate random sentence starting with. 155 | 156 | ``` r 157 | markovify_text( 158 | markov_model = markov_model, 159 | maximum_sentence_length = NULL, 160 | start_words = c("The", "You", "Life"), 161 | output_column_name = 'textLinnemanBot', 162 | count = 25, 163 | tries = 100, 164 | only_distinct = TRUE, 165 | return_message = TRUE 166 | ) 167 | ``` 168 | 169 | ## textLinnemanBot: The machine is rarely the problem; the people you love 170 | 171 | ## textLinnemanBot: The machine is rarely the problem; the people who matter know how you feel about them 172 | 173 | ## textLinnemanBot: The machine is rarely the problem; the people operating the machine are the ultimate assets 174 | 175 | ## textLinnemanBot: The machine is rarely the problem; the people who matter know how you could have made it better 176 | 177 | ## textLinnemanBot: You may never get a second chance to tell people how you could have made it better 178 | 179 | ## textLinnemanBot: Life isn’t fair, so don’t be upset when things break 180 | 181 | ## textLinnemanBot: Life isn’t fair, so don’t take it personally if yours are strange and difficult 182 | 183 | ## textLinnemanBot: Life will end; face it and embrace the joy of their life rather than the best you can? 184 | 185 | ## textLinnemanBot: Life isn’t fair, so don’t go crazy when things are unfair 186 | 187 | ## textLinnemanBot: Life isn’t fair, so don’t go crazy when things break 188 | 189 | ## textLinnemanBot: Life will end; face it and embrace the joy of their life rather than the sadness of their life rather than the best you can? 190 | 191 | ## textLinnemanBot: Life will end; face it and embrace the joy of their life rather than the sadness of their life rather than the sadness of their life rather than the sadness of their death 192 | 193 | ## textLinnemanBot: Life isn’t fair, so don’t take it personally if yours are strange and difficult; so don’t go crazy when things break 194 | 195 | ## textLinnemanBot: Life will end; face it and embrace the joy of their life rather than the best you that you can be 196 | 197 | ## textLinnemanBot: Life will end; face it and embrace the joy of their life rather than the sadness of their life rather than the sadness of their life rather than the best you that you can be 198 | 199 | ## # A tibble: 15 x 3 200 | ## idRow wordStart textLinnemanBot 201 | ## 202 | ## 1 1 The "The machine is rarely the problem; the people you love" 203 | ## 2 2 The "The machine is rarely the problem; the people who matter know how you feel about them" 204 | ## 3 3 The "The machine is rarely the problem; the people operating the machine are the ultimate assets" 205 | ## 4 4 The "The machine is rarely the problem; the people who matter know how you could have made it better" 206 | ## 5 1 You "You may never get a second chance to tell people how you could have made it better" 207 | ## 6 1 Life "Life isn’t fair, so don’t be upset when things break" 208 | ## 7 2 Life "Life isn’t fair, so don’t take it personally if yours are strange and difficult" 209 | ## 8 3 Life "Life will end; face it and embrace the joy of their life rather than the best you can?" 210 | ## 9 4 Life "Life isn’t fair, so don’t go crazy when things are unfair" 211 | ## 10 5 Life "Life isn’t fair, so don’t go crazy when things break" 212 | ## 11 6 Life "Life will end; face it and embrace the joy of their life rather than the sadness of their life rat… 213 | ## 12 7 Life "Life will end; face it and embrace the joy of their life rather than the sadness of their life rat… 214 | ## 13 8 Life "Life isn’t fair, so don’t take it personally if yours are strange and difficult; so don’t go crazy… 215 | ## 14 9 Life "Life will end; face it and embrace the joy of their life rather than the best you that you can be" 216 | ## 15 10 Life "Life will end; face it and embrace the joy of their life rather than the sadness of their life rat… 217 | 218 | Look at corpus start-words 219 | 220 | ``` r 221 | generate_start_words(markov_model = markov_model) 222 | ``` 223 | 224 | ## # A tibble: 63 x 3 225 | ## idSentence wordStart distanceCumulative 226 | ## 227 | ## 1 1 There 3 228 | ## 2 2 Travel, 4 229 | ## 3 3 Genius 5 230 | ## 4 4 Take 9 231 | ## 5 5 You 14 232 | ## 6 6 Analyze 15 233 | ## 7 7 Careers 16 234 | ## 8 8 Remember 17 235 | ## 9 9 Be 21 236 | ## 10 10 Life 23 237 | ## # ... with 53 more rows 238 | -------------------------------------------------------------------------------- /data/linneman_lessons.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abresler/markovifyR/187ffa9cb6a1c9c0d7a7a7c40af9cfe0819f5af5/data/linneman_lessons.rda -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • markovifyR 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | 48 | 49 | 50 |
51 |
52 | 92 | 93 | 94 |
95 | 96 |
97 |
98 | 101 | 102 |
    103 |
  • 104 |

    Alex Bresler. Maintainer. 105 |

    106 |
  • 107 |
108 | 109 |
110 | 111 |
112 | 113 | 114 |
115 | 118 | 119 |
120 |

Site built with pkgdown 1.3.0.9000.

121 |
122 |
123 |
124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/docsearch.css: -------------------------------------------------------------------------------- 1 | /* Docsearch -------------------------------------------------------------- */ 2 | /* 3 | Source: https://github.com/algolia/docsearch/ 4 | License: MIT 5 | */ 6 | 7 | .algolia-autocomplete { 8 | display: block; 9 | -webkit-box-flex: 1; 10 | -ms-flex: 1; 11 | flex: 1 12 | } 13 | 14 | .algolia-autocomplete .ds-dropdown-menu { 15 | width: 100%; 16 | min-width: none; 17 | max-width: none; 18 | padding: .75rem 0; 19 | background-color: #fff; 20 | background-clip: padding-box; 21 | border: 1px solid rgba(0, 0, 0, .1); 22 | box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); 23 | } 24 | 25 | @media (min-width:768px) { 26 | .algolia-autocomplete .ds-dropdown-menu { 27 | width: 175% 28 | } 29 | } 30 | 31 | .algolia-autocomplete .ds-dropdown-menu::before { 32 | display: none 33 | } 34 | 35 | .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { 36 | padding: 0; 37 | background-color: rgb(255,255,255); 38 | border: 0; 39 | max-height: 80vh; 40 | } 41 | 42 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { 43 | margin-top: 0 44 | } 45 | 46 | .algolia-autocomplete .algolia-docsearch-suggestion { 47 | padding: 0; 48 | overflow: visible 49 | } 50 | 51 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header { 52 | padding: .125rem 1rem; 53 | margin-top: 0; 54 | font-size: 1.3em; 55 | font-weight: 500; 56 | color: #00008B; 57 | border-bottom: 0 58 | } 59 | 60 | .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { 61 | float: none; 62 | padding-top: 0 63 | } 64 | 65 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { 66 | float: none; 67 | width: auto; 68 | padding: 0; 69 | text-align: left 70 | } 71 | 72 | .algolia-autocomplete .algolia-docsearch-suggestion--content { 73 | float: none; 74 | width: auto; 75 | padding: 0 76 | } 77 | 78 | .algolia-autocomplete .algolia-docsearch-suggestion--content::before { 79 | display: none 80 | } 81 | 82 | .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { 83 | padding-top: .75rem; 84 | margin-top: .75rem; 85 | border-top: 1px solid rgba(0, 0, 0, .1) 86 | } 87 | 88 | .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { 89 | display: block; 90 | padding: .1rem 1rem; 91 | margin-bottom: 0.1; 92 | font-size: 1.0em; 93 | font-weight: 400 94 | /* display: none */ 95 | } 96 | 97 | .algolia-autocomplete .algolia-docsearch-suggestion--title { 98 | display: block; 99 | padding: .25rem 1rem; 100 | margin-bottom: 0; 101 | font-size: 0.9em; 102 | font-weight: 400 103 | } 104 | 105 | .algolia-autocomplete .algolia-docsearch-suggestion--text { 106 | padding: 0 1rem .5rem; 107 | margin-top: -.25rem; 108 | font-size: 0.8em; 109 | font-weight: 400; 110 | line-height: 1.25 111 | } 112 | 113 | .algolia-autocomplete .algolia-docsearch-footer { 114 | width: 110px; 115 | height: 20px; 116 | z-index: 3; 117 | margin-top: 10.66667px; 118 | float: right; 119 | font-size: 0; 120 | line-height: 0; 121 | } 122 | 123 | .algolia-autocomplete .algolia-docsearch-footer--logo { 124 | background-image: url("data:image/svg+xml;utf8,"); 125 | background-repeat: no-repeat; 126 | background-position: 50%; 127 | background-size: 100%; 128 | overflow: hidden; 129 | text-indent: -9000px; 130 | width: 100%; 131 | height: 100%; 132 | display: block; 133 | transform: translate(-8px); 134 | } 135 | 136 | .algolia-autocomplete .algolia-docsearch-suggestion--highlight { 137 | color: #FF8C00; 138 | background: rgba(232, 189, 54, 0.1) 139 | } 140 | 141 | 142 | .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { 143 | box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) 144 | } 145 | 146 | .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { 147 | background-color: rgba(192, 192, 192, .15) 148 | } 149 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body > .container { 21 | display: flex; 22 | height: 100%; 23 | flex-direction: column; 24 | 25 | padding-top: 60px; 26 | } 27 | 28 | body > .container .row { 29 | flex: 1 0 auto; 30 | } 31 | 32 | footer { 33 | margin-top: 45px; 34 | padding: 35px 0 36px; 35 | border-top: 1px solid #e5e5e5; 36 | color: #666; 37 | display: flex; 38 | flex-shrink: 0; 39 | } 40 | footer p { 41 | margin-bottom: 0; 42 | } 43 | footer div { 44 | flex: 1; 45 | } 46 | footer .pkgdown { 47 | text-align: right; 48 | } 49 | footer p { 50 | margin-bottom: 0; 51 | } 52 | 53 | img.icon { 54 | float: right; 55 | } 56 | 57 | img { 58 | max-width: 100%; 59 | } 60 | 61 | /* Fix bug in bootstrap (only seen in firefox) */ 62 | summary { 63 | display: list-item; 64 | } 65 | 66 | /* Typographic tweaking ---------------------------------*/ 67 | 68 | .contents .page-header { 69 | margin-top: calc(-60px + 1em); 70 | } 71 | 72 | /* Section anchors ---------------------------------*/ 73 | 74 | a.anchor { 75 | margin-left: -30px; 76 | display:inline-block; 77 | width: 30px; 78 | height: 30px; 79 | visibility: hidden; 80 | 81 | background-image: url(./link.svg); 82 | background-repeat: no-repeat; 83 | background-size: 20px 20px; 84 | background-position: center center; 85 | } 86 | 87 | .hasAnchor:hover a.anchor { 88 | visibility: visible; 89 | } 90 | 91 | @media (max-width: 767px) { 92 | .hasAnchor:hover a.anchor { 93 | visibility: hidden; 94 | } 95 | } 96 | 97 | 98 | /* Fixes for fixed navbar --------------------------*/ 99 | 100 | .contents h1, .contents h2, .contents h3, .contents h4 { 101 | padding-top: 60px; 102 | margin-top: -40px; 103 | } 104 | 105 | /* Static header placement on mobile devices */ 106 | @media (max-width: 767px) { 107 | .navbar-fixed-top { 108 | position: absolute; 109 | } 110 | .navbar { 111 | padding: 0; 112 | } 113 | } 114 | 115 | 116 | /* Sidebar --------------------------*/ 117 | 118 | #sidebar { 119 | margin-top: 30px; 120 | } 121 | #sidebar h2 { 122 | font-size: 1.5em; 123 | margin-top: 1em; 124 | } 125 | 126 | #sidebar h2:first-child { 127 | margin-top: 0; 128 | } 129 | 130 | #sidebar .list-unstyled li { 131 | margin-bottom: 0.5em; 132 | } 133 | 134 | .orcid { 135 | height: 16px; 136 | vertical-align: middle; 137 | } 138 | 139 | /* Reference index & topics ----------------------------------------------- */ 140 | 141 | .ref-index th {font-weight: normal;} 142 | 143 | .ref-index td {vertical-align: top;} 144 | .ref-index .icon {width: 40px;} 145 | .ref-index .alias {width: 40%;} 146 | .ref-index-icons .alias {width: calc(40% - 40px);} 147 | .ref-index .title {width: 60%;} 148 | 149 | .ref-arguments th {text-align: right; padding-right: 10px;} 150 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 151 | .ref-arguments .name {width: 20%;} 152 | .ref-arguments .desc {width: 80%;} 153 | 154 | /* Nice scrolling for wide elements --------------------------------------- */ 155 | 156 | table { 157 | display: block; 158 | overflow: auto; 159 | } 160 | 161 | /* Syntax highlighting ---------------------------------------------------- */ 162 | 163 | pre { 164 | word-wrap: normal; 165 | word-break: normal; 166 | border: 1px solid #eee; 167 | } 168 | 169 | pre, code { 170 | background-color: #f8f8f8; 171 | color: #333; 172 | } 173 | 174 | pre code { 175 | overflow: auto; 176 | word-wrap: normal; 177 | white-space: pre; 178 | } 179 | 180 | pre .img { 181 | margin: 5px 0; 182 | } 183 | 184 | pre .img img { 185 | background-color: #fff; 186 | display: block; 187 | height: auto; 188 | } 189 | 190 | code a, pre a { 191 | color: #375f84; 192 | } 193 | 194 | a.sourceLine:hover { 195 | text-decoration: none; 196 | } 197 | 198 | .fl {color: #1514b5;} 199 | .fu {color: #000000;} /* function */ 200 | .ch,.st {color: #036a07;} /* string */ 201 | .kw {color: #264D66;} /* keyword */ 202 | .co {color: #888888;} /* comment */ 203 | 204 | .message { color: black; font-weight: bolder;} 205 | .error { color: orange; font-weight: bolder;} 206 | .warning { color: #6A0366; font-weight: bolder;} 207 | 208 | /* Clipboard --------------------------*/ 209 | 210 | .hasCopyButton { 211 | position: relative; 212 | } 213 | 214 | .btn-copy-ex { 215 | position: absolute; 216 | right: 0; 217 | top: 0; 218 | visibility: hidden; 219 | } 220 | 221 | .hasCopyButton:hover button.btn-copy-ex { 222 | visibility: visible; 223 | } 224 | 225 | /* mark.js ----------------------------*/ 226 | 227 | mark { 228 | background-color: rgba(255, 255, 51, 0.5); 229 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 230 | padding: 1px; 231 | } 232 | 233 | /* vertical spacing after htmlwidgets */ 234 | .html-widget { 235 | margin-bottom: 10px; 236 | } 237 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $("#sidebar") 6 | .stick_in_parent({offset_top: 40}) 7 | .on('sticky_kit:bottom', function(e) { 8 | $(this).parent().css('position', 'static'); 9 | }) 10 | .on('sticky_kit:unbottom', function(e) { 11 | $(this).parent().css('position', 'relative'); 12 | }); 13 | 14 | $('body').scrollspy({ 15 | target: '#sidebar', 16 | offset: 60 17 | }); 18 | 19 | $('[data-toggle="tooltip"]').tooltip(); 20 | 21 | var cur_path = paths(location.pathname); 22 | var links = $("#navbar ul li a"); 23 | var max_length = -1; 24 | var pos = -1; 25 | for (var i = 0; i < links.length; i++) { 26 | if (links[i].getAttribute("href") === "#") 27 | continue; 28 | // Ignore external links 29 | if (links[i].host !== location.host) 30 | continue; 31 | 32 | var nav_path = paths(links[i].pathname); 33 | 34 | var length = prefix_length(nav_path, cur_path); 35 | if (length > max_length) { 36 | max_length = length; 37 | pos = i; 38 | } 39 | } 40 | 41 | // Add class to parent
  • , and enclosing
  • if in dropdown 42 | if (pos >= 0) { 43 | var menu_anchor = $(links[pos]); 44 | menu_anchor.parent().addClass("active"); 45 | menu_anchor.closest("li.dropdown").addClass("active"); 46 | } 47 | }); 48 | 49 | function paths(pathname) { 50 | var pieces = pathname.split("/"); 51 | pieces.shift(); // always starts with / 52 | 53 | var end = pieces[pieces.length - 1]; 54 | if (end === "index.html" || end === "") 55 | pieces.pop(); 56 | return(pieces); 57 | } 58 | 59 | // Returns -1 if not found 60 | function prefix_length(needle, haystack) { 61 | if (needle.length > haystack.length) 62 | return(-1); 63 | 64 | // Special case for length-0 haystack, since for loop won't run 65 | if (haystack.length === 0) { 66 | return(needle.length === 0 ? 0 : -1); 67 | } 68 | 69 | for (var i = 0; i < haystack.length; i++) { 70 | if (needle[i] != haystack[i]) 71 | return(i); 72 | } 73 | 74 | return(haystack.length); 75 | } 76 | 77 | /* Clipboard --------------------------*/ 78 | 79 | function changeTooltipMessage(element, msg) { 80 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 81 | element.setAttribute('data-original-title', msg); 82 | $(element).tooltip('show'); 83 | element.setAttribute('data-original-title', tooltipOriginalTitle); 84 | } 85 | 86 | if(ClipboardJS.isSupported()) { 87 | $(document).ready(function() { 88 | var copyButton = ""; 89 | 90 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 91 | 92 | // Insert copy buttons: 93 | $(copyButton).prependTo(".hasCopyButton"); 94 | 95 | // Initialize tooltips: 96 | $('.btn-copy-ex').tooltip({container: 'body'}); 97 | 98 | // Initialize clipboard: 99 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 100 | text: function(trigger) { 101 | return trigger.parentNode.textContent; 102 | } 103 | }); 104 | 105 | clipboardBtnCopies.on('success', function(e) { 106 | changeTooltipMessage(e.trigger, 'Copied!'); 107 | e.clearSelection(); 108 | }); 109 | 110 | clipboardBtnCopies.on('error', function() { 111 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 112 | }); 113 | }); 114 | } 115 | })(window.jQuery || window.$) 116 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.6' 2 | pkgdown: 1.3.0.9000 3 | pkgdown_sha: 7e788c41d20ab28d4bf97556e18382391d359c9f 4 | articles: [] 5 | 6 | -------------------------------------------------------------------------------- /inst/examples/bap_example.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | library(markovifyR) 3 | setwd("~") 4 | bap <- read_lines("Downloads/bap.txt", skip_empty_rows = T) 5 | 6 | tbl_bap <- tibble(bapism = bap) %>% 7 | mutate(bapism = str_replace_all(bapism, '[\"]', '')) %>% 8 | separate( 9 | bapism, 10 | into = c("bapism", "speaker"), 11 | sep = "\\ - ", 12 | extra = "merge", 13 | fill = "right" 14 | ) %>% 15 | mutate(speaker = speaker %>% coalesce("BAP")) 16 | 17 | sexy_bap <- 18 | tbl_bap %>% 19 | filter(speaker == "BAP") %>% 20 | dplyr::select(bapism) %>% 21 | pull() 22 | 23 | 24 | markov_model <- 25 | generate_markovify_model( 26 | input_text = sexy_bap, 27 | markov_state_size = 3L, 28 | max_overlap_total = 35, 29 | max_overlap_ratio = .95 30 | ) 31 | 32 | 33 | bap_bot <- markovify_text( 34 | markov_model = markov_model, 35 | maximum_sentence_length = NULL, 36 | output_column_name = 'bap_bot', 37 | count = 50, 38 | tries = 100, 39 | only_distinct = TRUE, 40 | return_message = TRUE 41 | ) 42 | 43 | markovify_text( 44 | markov_model = markov_model, 45 | maximum_sentence_length = NULL, 46 | output_column_name = 'bap_bot', 47 | count = 50, 48 | tries = 100, 49 | start_words = c("Wuhan", "Communists"), 50 | only_distinct = TRUE, 51 | return_message = TRUE 52 | ) -------------------------------------------------------------------------------- /man/combine_markov_models.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{combine_markov_models} 4 | \alias{combine_markov_models} 5 | \title{Combine markov models} 6 | \usage{ 7 | combine_markov_models(model_a, model_b, weights = c(1, 1.5)) 8 | } 9 | \arguments{ 10 | \item{model_a}{first model} 11 | 12 | \item{model_b}{second model} 13 | 14 | \item{weights}{numeric vector of 2 weights 15 | defaults are \code{c(1, 1.5)}} 16 | } 17 | \description{ 18 | Builds a combined 19 | markov model 20 | } 21 | -------------------------------------------------------------------------------- /man/export_markov_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{export_markov_model} 4 | \alias{export_markov_model} 5 | \title{Export Markov Model} 6 | \usage{ 7 | export_markov_model(markov_model, format = "json") 8 | } 9 | \arguments{ 10 | \item{markov_model}{a markov model object} 11 | 12 | \item{format}{\itemize{ 13 | \item json - returns a json object 14 | \item dict - returns dictionary object 15 | }} 16 | } 17 | \value{ 18 | a json or dictionary object 19 | } 20 | \description{ 21 | Export Markov Model 22 | } 23 | -------------------------------------------------------------------------------- /man/generate_corpus.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{generate_corpus} 4 | \alias{generate_corpus} 5 | \title{Generate a corpus from a 6 | markov model} 7 | \usage{ 8 | generate_corpus(markov_model, input_text) 9 | } 10 | \arguments{ 11 | \item{markov_model}{markov model object} 12 | 13 | \item{input_text}{vector of input text} 14 | } 15 | \description{ 16 | Generate a corpus from a 17 | markov model 18 | } 19 | -------------------------------------------------------------------------------- /man/generate_markovify_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{generate_markovify_model} 4 | \alias{generate_markovify_model} 5 | \title{Generate Markovify model} 6 | \usage{ 7 | generate_markovify_model( 8 | input_text, 9 | markov_state_size = 2, 10 | max_overlap_total = 15, 11 | max_overlap_ratio = 0.7, 12 | tries = 100 13 | ) 14 | } 15 | \arguments{ 16 | \item{input_text}{a \code{vector} of text} 17 | 18 | \item{markov_state_size}{markov state to use 19 | \code{default} is 2} 20 | 21 | \item{max_overlap_total}{maximum overlap total 22 | default is \code{15}} 23 | 24 | \item{max_overlap_ratio}{maximum overlap ratio 25 | \code{default is .7}} 26 | 27 | \item{tries}{number over times to try to generate a sentence} 28 | } 29 | \value{ 30 | a markov model in Python object form 31 | } 32 | \description{ 33 | Generate a markov model for a 34 | given input text and set of model 35 | parameters 36 | } 37 | \examples{ 38 | \dontrun{ 39 | library(dplyr) 40 | library(markovifyR) 41 | data("linneman_lessons") 42 | df <- linneman_lessons 43 | lessons <- 44 | df \%>\% 45 | pull(textLesson) 46 | markov_model <- 47 | generate_markovify_model( 48 | input_text = lessons, 49 | markov_state_size = 3L, 50 | max_overlap_total = 15, 51 | max_overlap_ratio = .8 52 | ) 53 | markov_model 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /man/generate_parsed_sentences.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{generate_parsed_sentences} 4 | \alias{generate_parsed_sentences} 5 | \title{Generate parsed sentences} 6 | \usage{ 7 | generate_parsed_sentences(markov_model) 8 | } 9 | \arguments{ 10 | \item{markov_model}{} 11 | } 12 | \value{ 13 | a \code{list} 14 | } 15 | \description{ 16 | This function returns the parsed input 17 | text in sentence form 18 | } 19 | -------------------------------------------------------------------------------- /man/generate_start_words.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{generate_start_words} 4 | \alias{generate_start_words} 5 | \title{Generate start words} 6 | \usage{ 7 | generate_start_words(markov_model, include_cumulative_distance = TRUE) 8 | } 9 | \arguments{ 10 | \item{markov_model}{markov model mobject} 11 | 12 | \item{include_cumulative_distance}{if \code{TRUE} returns 13 | cumulative distance of the words} 14 | } 15 | \value{ 16 | a \code{tibble} objects 17 | } 18 | \description{ 19 | Generate start words 20 | } 21 | -------------------------------------------------------------------------------- /man/get_data_linneman_lessons.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/linneman.R 3 | \name{get_data_linneman_lessons} 4 | \alias{get_data_linneman_lessons} 5 | \title{Newest Linneman lessons} 6 | \usage{ 7 | get_data_linneman_lessons() 8 | } 9 | \value{ 10 | a \code{tibble} 11 | } 12 | \description{ 13 | Newest Linneman lessons 14 | } 15 | \examples{ 16 | get_data_linneman_lessons() 17 | } 18 | \references{ 19 | \url{asbcllc.com/reflections/peter_linneman/} 20 | } 21 | -------------------------------------------------------------------------------- /man/install_markovify.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{install_markovify} 4 | \alias{install_markovify} 5 | \title{Install Markovify Python module} 6 | \usage{ 7 | install_markovify() 8 | } 9 | \value{ 10 | invisible 11 | } 12 | \description{ 13 | Install Markovify Python module 14 | } 15 | \examples{ 16 | \dontrun{ 17 | install_markovify() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /man/linneman_lessons.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{linneman_lessons} 5 | \alias{linneman_lessons} 6 | \title{Peter Linneman's life lessons} 7 | \format{ 8 | Data frame with columns 9 | \describe{ 10 | \item{idLesson}{Lesson Number} 11 | \item{textLesson}{Lesson Text} 12 | ... 13 | } 14 | } 15 | \source{ 16 | \url{https://asbcllc.com/reflections/peter_linneman/} 17 | } 18 | \usage{ 19 | linneman_lessons 20 | } 21 | \description{ 22 | List of Peter Linnemans life lessons 23 | } 24 | \keyword{datasets} 25 | -------------------------------------------------------------------------------- /man/markovifyR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovifyR-package.R 3 | \docType{package} 4 | \name{markovifyR} 5 | \alias{markovifyR} 6 | \title{Markovify wrapper for R} 7 | \author{ 8 | Alex Bresler (abresler@asbcllc.com) 9 | } 10 | -------------------------------------------------------------------------------- /man/markovify_text.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/markovify.R 3 | \name{markovify_text} 4 | \alias{markovify_text} 5 | \title{Markovify text} 6 | \usage{ 7 | markovify_text( 8 | markov_model, 9 | maximum_sentence_length = NULL, 10 | start_words = NULL, 11 | output_column_name = "columnName", 12 | count = 50, 13 | tries = 100, 14 | only_distinct = TRUE, 15 | return_message = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{markov_model}{a markov model produced from \code{generate_markovify_model}} 20 | 21 | \item{maximum_sentence_length}{the maximum length of the sentence 22 | if \code{NULL} model will produce a random sentence of any length.} 23 | 24 | \item{start_words}{a markov model produced with a list of start word terms} 25 | 26 | \item{output_column_name}{name of the} 27 | 28 | \item{count}{count of the number of sentences, default \code{50}} 29 | 30 | \item{tries}{count of the number of tries to produce a coherent sentence} 31 | 32 | \item{only_distinct}{if \code{TRUE} returns only distinct text} 33 | 34 | \item{return_message}{if \code{TRUE} returns a message} 35 | } 36 | \value{ 37 | a \code{tibble} 38 | } 39 | \description{ 40 | Produces text output from 41 | a markov model based pn user specified 42 | parameters 43 | } 44 | \examples{ 45 | \dontrun{ 46 | library(dplyr) 47 | library(markovifyR) 48 | data("linneman_lessons") 49 | df <- linneman_lessons 50 | lessons <- df \%>\% pull(textLesson) 51 | markov_model <- 52 | generate_markovify_model( 53 | input_text = lessons, 54 | markov_state_size = 2L, 55 | max_overlap_total = 15, 56 | max_overlap_ratio = .8) 57 | 58 | markovify_text( 59 | markov_model = markov_model, 60 | count = 100, 61 | maximum_sentence_length = 1500L, 62 | output_column_name = 'linnemanBotText', 63 | tries = 100, 64 | only_distinct = TRUE, 65 | return_message = TRUE 66 | ) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /markovifyR.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | StripTrailingWhitespace: Yes 16 | 17 | BuildType: Package 18 | PackageUseDevtools: Yes 19 | PackageInstallArgs: --no-multiarch --with-keep.source 20 | PackageRoxygenize: rd,collate,namespace,vignette 21 | --------------------------------------------------------------------------------