The imguR package seems to be exactly what I want, but a scan of the docs makes it seem like it only uploads files. Can I upload the current plot device without outputting to a file? Specifically I'm interested in uploading plots created with ggplot2. Here is what I tried:
> token = imgur_login()
> ggplot(dstat, aes(x=obs,y=tcp)) + geom_line() + theme_bw()
> upload_image(token=token)
Error in file.exists(file) : argument "file" is missing, with no default
EDIT: I should add, I'm comfortable with a method that invisibly creates a file in the background then uploads it, this is just for quick showcasing of plots not for perfect presentation
EDIT: Here is the code I have created so far. It does not work well because there seems to be a cache used inside of account_albums that is not easily disabled. Any help finalizing this would be appreciated
get_or_create_album = function(token) {
# I can find no way to disable the cache inside
# account_albums - it always returns the first
# result unless you login again.
# So if this function creates the album, then
# the user must manually log out and log back in
# or this function will happily continue creating the album
albums = account_albums(ids=F,token=token)
albums = data.frame(t(sapply(albums,c)))
album = albums$id[albums$title == "R ggplot2"]
if (length(album) >= 1)
return(album[[1]])
album = create_album(title='R ggplot2',description='Automatic uploads from ggplot2',privacy='public', token=token)
return(album$id)
}
ggupload = function(token) {
albumID = get_or_create_album(token)
x = tempfile(fileext = '.pdf')
ggsave(filename=x)
p = last_plot()
title = ""
desc = ""
labels = names(p$labels)
if ("x" %in% labels && "y" %in% labels)
title = paste(p$labels$x,"vs",p$labels$y)
desc = title
if ("title" %in% labels)
title = p$labels$title
imgur_upload(file = x, album = albumID, title=title, description = desc, token = token)
}
This works as follows
> token = imgur_login()
> ggplot(dstat, aes(x=obs,y=tcp)) + geom_line() + theme_bw()
> ggupload(token)
Related
In png(), the first argument is filename = "Rplot%03d.png" which causes files to be generated with ascending numbers. However, in ggsave, this doesn't work, the number always stays at the lowest number (Rplots001.png") and this file is always overwritten.
Looking at the code of the grDevices-functions (e.g. grDevices::png() it appears that the automatic naming happens in functions which are called by .External()
Is there already an implementation of this file naming functionality in R such that it is accessible outside of the grDevices functions?
Edit:
asked differently, is there a way to continue automatic numbering after shutting off and restarting a device? For example, in this code, the two later files overwrite the former ones:
png(width = 100)
plot(1:10)
plot(1:10)
dev.off()
png(width = 1000)
plot(1:10)
plot(1:10)
dev.off()
You can write a function to do this. For example, how about simply adding a time stamp. something like:
fname = function(basename = 'myfile', fileext = 'png'){
paste(basename, format(Sys.time(), " %b-%d-%Y %H-%M-%S."), fileext, sep="")
}
ggsave(fname())
Or, if you prefer sequential numbering, then something along the lines of
next_file = function(basename = 'myfile', fileext = 'png', filepath = '.'){
old.fnames = grep(paste0(basename,' \\d+\\.', fileext,'$'),
list.files(filepath), value = T)
lastnum = gsub(paste0(basename,' (\\d+)\\.', fileext,'$'), '\\1', old.fnames)
if (!length(lastnum)) {
lastnum = 1
} else {
lastnum = sort(as.integer(lastnum),T)[1] + 1L
}
return(paste0(basename, ' ', sprintf('%03i', lastnum), '.', fileext))
}
ggsave(next_file())
I'm using slackr to send alert messages to a Slack channel. It works great except the message format is not great and I want to improve it.
install_github("hrbrmstr/slackr")
library(slackr)
slackr_setup(channel="#alerts", username="Mark Davis",
incoming_webhook_url = "https://hooks.slack.com/services/T31P8UDAB/BCH4HKQSC/*********",
api_token = "*********", echo = F)
alert="On Monday, 2018-09-03 # 2pm Pacific..."
slackr(alert)
Here is an example of how a message from slackr looks in Slack:
Here is an example of how I'd like it to look:
slackr doesn't seem to have many options in the way of formatting. I was thinking of building an image and inserting that, but I'm having trouble building an image out of a text file using R.
Perhaps there is another api I could call that could take my text and format it for slack?
I'm open to any suggestions.
Addendum:
Slackr has an option to upload files, so my latest attempt is to create an image from the text message and upload that object.
I am able to create a png file from the text message using the magick library. I created an image with a colored background, and I simply add the message text to the image:
library(magick)
alert_picture <- image_read('alert_480x150_dark_red.png')
alert_picture=image_annotate(alert_picture, DreamCloud_Alert, size = 20, gravity = "southwest",
color = "white", location = "+10+10")
image_write(alert_picture, path = "alert_picture.png", format = "png")
The image looks pretty good (although there doesn't seem to be an easy way to bold or underline specific words in the message), but the obstacle now is that I can't get the upload command to work.
slackr_upload(filename = "alert_picture.png")
I don't get any error messages but nothing is uploaded to slack.
I got around this issue by using the httr package to execute the post image function to slack.
Thanks to Adil B. for providing the solution:
Post Image to Slack Using HTTR package in R
I am not sure this is what you meant, but I solved allowing formatting like in a regular slack message by altering the slackr_bot() function and just removing the 2 sets of 3 back-ticks at the end of the code where it says text. Then just call it slackr_bot1() or something, and then you can post formatted messages. This is the function after the back-ticks removal:
slackr_bot1 <- function(...,
channel=Sys.getenv("SLACK_CHANNEL"),
username=Sys.getenv("SLACK_USERNAME"),
icon_emoji=Sys.getenv("SLACK_ICON_EMOJI"),
incoming_webhook_url=Sys.getenv("SLACK_INCOMING_URL_PREFIX")) {
if (incoming_webhook_url == "") {
stop("No incoming webhook URL specified. Did you forget to call slackr_setup()?", call. = FALSE)
}
if (icon_emoji != "") { icon_emoji <- sprintf(', "icon_emoji": "%s"', icon_emoji) }
resp_ret <- ""
if (!missing(...)) {
# mimics capture.output
# get the arglist
args <- substitute(list(...))[-1L]
# setup in-memory sink
rval <- NULL
fil <- textConnection("rval", "w", local = TRUE)
sink(fil)
on.exit({
sink()
close(fil)
})
# where we'll need to eval expressions
pf <- parent.frame()
# how we'll eval expressions
evalVis <- function(expr) withVisible(eval(expr, pf))
# for each expression
for (i in seq_along(args)) {
expr <- args[[i]]
# do something, note all the newlines...Slack ``` needs them
tmp <- switch(mode(expr),
# if it's actually an expresison, iterate over it
expression = {
cat(sprintf("> %s\n", deparse(expr)))
lapply(expr, evalVis)
},
# if it's a call or a name, eval, printing run output as if in console
call = ,
name = {
cat(sprintf("> %s\n", deparse(expr)))
list(evalVis(expr))
},
# if pretty much anything else (i.e. a bare value) just output it
integer = ,
double = ,
complex = ,
raw = ,
logical = ,
numeric = cat(sprintf("%s\n\n", as.character(expr))),
character = cat(sprintf("%s\n\n", expr)),
stop("mode of argument not handled at present by slackr"))
for (item in tmp) if (item$visible) { print(item$value, quote = FALSE); cat("\n") }
}
on.exit()
sink()
close(fil)
# combined all of them (rval is a character vector)
output <- paste0(rval, collapse="\n")
loc <- Sys.getlocale('LC_CTYPE')
Sys.setlocale('LC_CTYPE','C')
on.exit(Sys.setlocale("LC_CTYPE", loc))
resp <- POST(url = incoming_webhook_url, encode = "form",
add_headers(`Content-Type` = "application/x-www-form-urlencoded",
Accept = "*/*"), body = URLencode(sprintf("payload={\"channel\": \"%s\", \"username\": \"%s\", \"text\": \"%s\"%s}",
channel, username, output, icon_emoji)))
warn_for_status(resp)
}
return(invisible())
}
slackr_bot1("*test* on time")
I have R function [here is script, here is package] that works perfectly in console, but when I build and load package, something goes wrong
In console environment, I create vector, create function, assign the variable to pass to function, and output is as expected when I execute ListPalette(listname)
> PunjabiPalette <- list (
+ AmritsariKulcha = c("#e3e4d9", "#ebdc9c", "#b3340e", "#67140a", "#2a231d"),
+ CholeBhature = c("#7cab70", "#d9bf9c", "#a04d05", "#995f7e", "#972107"),
+ FieldsOfPunjab = c("#fda726", "#d75b07", "#702e06", "#514617", "#313407"),
+ FieldsOfPunjab2 = c("#9aa5b4", "#516e9c", "#13306a", "#94aa0b", "#a36316"),
+ GoldenTemple = c("#bdcad0", "#5f8abf", "#ffd860", "#d88821", "#672006"),
+ GoldenTemple2 = c("#7d84cb", "#374890","#c2592e", "#fa5102", "#722416"),
+ Pindh = c("#5eb39c", "#1f6562","#2168c2", "#d77e5f", "#5f3e25"),
+ SohniMahiwal = c("#dc6478", "#a9365a", "#f4420e", "#403c61", "#313f42"),
+ HeerRanjha = c("#93dd7d","#3272b6", "#ec9382", "#ab3a40", "#072246"),
+ Gidha = c("#fdea6e", "#4aec6a", "#fb7894", "#f13111", "#2584a0"),
+ Gidha2 = c("#fb9961", "#f13375", "#771341", "#2d3c2f", "#ea263c"),
+ Teej = c("#22325f", "#88ce64", "#fbd234", "#b8091f", "#682f4e"),
+ Phulkari = c("#efa20b", "#04a193", "#14555d","#820203", "#ed2e06"),
+ Phulkari2 = c("#9c1a41", "#42a4e8", "#3a35da", "#ee523c", "#3e167c"),
+ Jutti = c("#460809", "#00699e", "#391b72", "#03471d", "#ba0841"),
+ Jutti2 = c("#e278e5", "#13187e", "#fb6225", "#f23561", "#d2b88f"),
+ Jutti3 = c("#6fa42c", "#db3717", "#051a8d", "#ef38a7", "#202c3d"),
+ Paranda = c("#eaa32b", "#f45d59", "#c33dd2", "#92214c", "#201274")
+ )
> ListPalette <- function(listname){
+ names(listname)
+ }
> listname <- PunjabiPalette
> ListPalette(listname)
[1] "AmritsariKulcha" "CholeBhature" "FieldsOfPunjab" "FieldsOfPunjab2" "GoldenTemple" "GoldenTemple2"
[7] "Pindh" "SohniMahiwal" "HeerRanjha" "Gidha" "Gidha2" "Teej"
[13] "Phulkari" "Phulkari2" "Jutti" "Jutti2" "Jutti3" "Paranda"
>
However, when I run the same script, build the package locally and execute ListPalette(listname), I get following
> ListPalette("RanglaPunjab")
NULL
Something is amiss. I thought it might be a silly oversight, but I've been wrangling over this for more than an hour .... please guide.
Try it without quotes.
ListPalette(RanglaPunjab)
If you want to use the name of the list as a character, you must use get.
ListPalette <- function(listname){
list <- get(listname)
names(list)
}
ListPalette("PunjabiPalette")
[1] "AmritsariKulcha" "CholeBhature" "FieldsOfPunjab" "FieldsOfPunjab2" "GoldenTemple" "GoldenTemple2" "Pindh"
[8] "SohniMahiwal" "HeerRanjha" "Gidha" "Gidha2" "Teej" "Phulkari" "Phulkari2"
[15] "Jutti" "Jutti2" "Jutti3" "Paranda"
I am crawling some sites.
The link is not correct.
The page does not open.
So I want to add a link to the original data
Or maybe there is a better way than I think.
Please let me know if there is a good way
-Ex-
[[A wrong address]]
/qna/detail.nhn?d1id=7&dirId=70111&docId=280474152
[[The text you want to add]]
I would like to add an address to the front of my code(# Bulletin url)
Http: // ~ naver.com
library(httr)
library(rvest)
library(stringr)
# Bulletin URL
list.url = 'http://kin.naver.com/qna/list.nhn?m=expertAnswer&dirId=70111'
# Vector to store title and body
titles = c()
contents = c()
# 1 to 10 page bulletin crawling
for(i in 1:10){
url = modify_url(list.url, query=list(page=i)) # Change the page in the bulletin URL
h.list = read_html(url, encoding = 'utf-8') # Get a list of posts, read and save html files from url
# Post link extraction
title.link1 = html_nodes(h.list, '.title') #class of title
title.links = html_nodes(title.link1, 'a') #title.link1 to a로
article.links = html_attr(title.links, 'href')
#Extract attrribute
for(link in article.links){
h = read_html(link) # Get the post
# title
title = html_text(html_nodes(h, '.end_question._end_wrap_box h3'))
title = str_trim(repair_encoding(title))
titles = c(titles, title)
# content
content = html_nodes(h, '.end_question .end_content._endContents')
## Mobile question content
no.content = html_text(html_nodes(content, '.end_ext2'))
content = repair_encoding(html_text(content))
## Mobile question content
## ex) http://kin.naver.com/qna/detail.nhn?d1id=8&dirId=8&docId=235904020&qb=7Jes65Oc66aE&enc=utf8§ion=kin&rank=19&search_sort=0&spq=1
if (length(no.content) > 0)
{
content = str_replace(content, repair_encoding(no.content), '')
}
content <- str_trim(content)
contents = c(contents, content)
print(link)
}
}
# save
result = data.frame(titles, contents)
If you add article.links <- paste0("http://kin.naver.com", article.links) before the forloop, this seems to work (running).
I'm using rCharts to create a scatterplot that displays ratings that I have calculated over time. I have more information for each individual data point (rating) and would like to have each data point on the graph link to a unique page with more information about that specific data point.
For example: I would like to be able to hover over the first data point on the graph and click on it to go to a specific page (http://www.example.com/info?id=1) that provides more information about that rating or data point. Each data point has a unique id and unique url that I would like to link to.
Here is the code that I am using to generate the graph
library(rCharts)
age <- c(1:20)
tall <- seq(0.5, 1.90, length = 20)
name <- paste(letters[1:20], 1:20, sep = "")
df <- data.frame(age = age, tall = tall, name = name)
n1 <- nPlot(age ~ tall ,data = df, type = "scatterChart")
n1$xAxis(axisLabel = "the age")
n1$yAxis(axisLabel = "the tall", width = 50)
n1$chart(tooltipContent = "#! function(key, x, y, e ){
var d = e.series.values[e.pointIndex];
return 'x: ' + x + ' y: ' + y + ' name: ' + d.name
} !#")
n1
This should definitely be considered a hack for now, but it works. Issues that we face here that cause us to require this hack are the draw function in the standard rCharts template does not offer us a place to add bits of code for nvd3, and the afterScript for nvd3 falls outside of our draw so is called before the chart is rendered. Also, the nvd3 tooltip is just html, but the problem with providing a link here to click is that mouseover is triggered and the tooltip disappears before we can click on it (fun trick but not useful). So, in this hack we will hijack the tooltip content function to also specify a click event function.
I tried to be clear with comments, but please let me know if none of this makes sense. I certainly do not make a career out of support :), so I have not built up that skill set.
library(rCharts)
age <- c(1:20)
tall <- seq(0.5, 1.90, length = 20)
name <- paste(letters[1:20], 1:20, sep = "")
#this next line is not entirely necessary if other data
#provides the part of the link address
#will also comment in the js piece below to show
#how to handle that
links <- paste0("http://example.com/",name)
df <- data.frame(age = age, tall = tall, name = name, links = links)
n1 <- nPlot(age ~ tall ,data = df, type = "scatterChart")
n1$xAxis(axisLabel = "the age")
n1$yAxis(axisLabel = "the tall", width = 50)
n1$chart(tooltipContent = "#! function(key, x, y, e ){
d3.selectAll('[class*=\"nv-path\"]').on('click',function(){
//uncomment debugger if you want to see what you have
//debugger;
window.open(d3.select(this).datum().data['point'][4].links,'_blank');
//as stated in the r code generating this
//the link address might be in the data that we already have
//window.open(
// 'http://example.com/' + d3.select(this).datum().data['point'][4].name,
// '_blank'
//);
})
//looks like the actual point is below the hover tooltip path
//if tooltips disabled we could do click on the actual points
//d3.selectAll('.nv-group circle').on('click',function(){
// debugger;
//})
var d = e.series.values[e.pointIndex];
return 'x: ' + x + ' y: ' + y + ' name: ' + d.name
} !#")
n1
I hope it helps.