I have a long vector containing emojis, something like this:
emojis <- c("😐","😥","😴","😉","😛")
and then I have their utf-8 encodings which I extracted with the help of devtools::install_github( "ThinkRstat/utf8splain") followed by library(utf8splain) like this, just for example: (not accurately represented)
emojis_enc <- c()
for(i in 1:length(emojis)){
emojis_enc <- c(emojis_enc, utf8splain::runes(emojis[i])$rune)
}
#emojis_enc <- c("U+12345","U+67891","U+91234","U+56789","U+123A6")
Then I have made a function this:
emojiPlot <- function(photo_enc, emo_char){
png(paste0(photo_enc, ".png"))
plot(emo_char, rescale = T, ylim = c(-1,1), xlim = c(-1,1))
dev.off()
}
And when I do this emojiPlot("emojis_enc[1]", emojis[1]) I just get an empty plot with x and y axis. I am pretty novice with UTF and R.
The reason why I am doing is because I am using a plugin called "imagepreview" in gephi software. And the plugin requires the nodes as photos. So my goal is to have individual emojis in .png and give them their utf encodings as the name. So when I import my data, I can just point the CSV containing the utfs to the names of the photos and pull the right emoji. And then just graph it.
I am doing this for a research project. I am open to better ways to do it.
I am in Ubuntu OS. If you use Windows, then emojis will show as their correct utf format, and won't be rendered.
Another solution to get to the png files of the emojis is to download them from Twitter, which accepts runes in the urls linking to the png files:
library(tidyverse)
data <- tibble(emojis = c("😐","😥","😴","😉","😛")) %>%
mutate(rune = map_chr(emojis, ~ utf8splain::runes(.)$rune)) %>% # convert to runes
mutate(rune = str_remove(rune, fixed("U+"))) %>% # remove leading U+
mutate(emoji_url = paste0("https://abs.twimg.com/emoji/v2/72x72/", # make url
tolower(rune), ".png"))
# download the files
map2(data$emoji_url, paste0(data$rune, ".png"), function(x, y) download.file(x, y, method = "curl"))
This will download the png files and place them in your working directory.
In base
The tidyverse code is optional, the same can be done in base:
emojis <- c("😐","😥","😴","😉","😛")
rune <- sapply(emojis, function(x) utf8splain::runes(x)$rune)
emojiurl <- paste0("https://abs.twimg.com/emoji/v2/72x72/", tolower(rune), ".png")
for (i in seq_along(emojiurl)) {
download.file(emojiurl[i], paste0(rune[i], ".png"), method = "curl")
}
You are plotting characters with plot when you should be using text.
In the code below, a plot is created with plot, argument type = "n", meaning, don't plot . Then the text (emoji) is added.
emojiPlot <- function(photo_enc, emo_char){
png(paste0(photo_enc, ".png"), units = "cm",
width = 10, height = 10, res = 600)
plot(0, 0, xlim = c(-1, 1), ylim = c(-1, 1), type = "n")
text(0, 0, emo_char)
dev.off()
}
emojiPlot("emojis_enc[1]", emojis[1])
The file "emojis_enc[1].png" is posted here:
Related
I am new in coding with R and I work with a large dataset.
I am trying to write a code that do the following things:
Get all pathes to all files in my folder
Extract the names of the files (as I want to name my plots after the input file)
Read in all files in my folder (these are all .csv files)
Plot a diagram for each .csv file by plotting groundwater level against the year
--> these plots should then get the title of the input file and also be stored under the same name.
For example when my file is called 211210.csv, then the title should be 211210 and stored as 211210.png
This is the code I have until know. As I said, I am new to R, and I tried to solve may problems I had in the code but I still run into new errors. Is there someone who can explain me where the problem is and how to solve it.
library(fs)
library(ggplot2)
library(tidyverse)
#Opening path to my data
filepath <- fs::dir_ls("D:/Desktop/Masterarbeit/Daten/Test/")
# Get name of files
name <- basename(filepath)
#Read every single files
file_content <- list()
for (i in seq_along(filepath)){
path <- filepath
file_content[[i]] <- read.csv(
file = filepath[[i]], header = TRUE
)
}
file_content <- set_names(file_content, filepath)
#Plot the diagram with gwl against year for each file, title = name of each file and store it in a seperat folder with the name of the input file
for (i in file_content){
mypath <- file.path("D:/Desktop/Masterarbeit/Daten/Results/", paste("Messstelle_", name[[i]], ".png", sep = ""))
png(file=mypath)
mytitle = paste("Messstelle", name[[i]])
plot(i$year, i$gwl,
pch = 19, #--> solid circle
cex = 1.5, #--> make 150% size
main = name[[i]],
xlab = "Year",
ylab = "Ground water level",
)
dev.off()
}
First I would prefer doing everything in one loop for efficiency. Second, I would avoid using unnecessary packages, e.g. fs (Base R has a good list.files function to list all files in a folder) Third, I would iterate through the names of the files and not through a numeric vector, e.g.:
filepath <- "D:/Desktop/Masterarbeit/Daten/Test/"
files <- list.files(filepath, pattern=".csv")
#Iterate through every single file
for (file in files){
name2store <- strsplit(file, "[.]")[[1]][1]
path2read <- file.path(filepath, file)
data <- read.csv(file =path2read, header = TRUE)
mypath <- file.path("D:/Desktop/Masterarbeit/Daten/Results/", paste("Messstelle_", name2store, ".png", sep = ""))
png(file=mypath)
mytitle = paste("Messstelle", name2store)
plot(data$year, data$gwl,
pch = 19, #--> solid circle
cex = 1.5, #--> make 150% size
main = name2store,
xlab = "Year",
ylab = "Ground water level",
)
dev.off()
}
I have a function that creates a plot and saves it as a pdf file. I plan on running this function in a loop for 100+ columns of a dataset. My question is how to make each pdf file uniquely named so it doesnt overwrite the previous file every time a new one is made. I tried to make it work with C integer format
pdf(file = "~/PTY/Data/ROC Curves/ROC%03d.pdf", onefile = F, width = 7, height = 7)
with the intended outcome of titling each plot ROC001, ROC002... but it still overwrites each new one as ROC001.
createROC <- function(x) {
ROCtable <- createNAtable(x) #create dataset w/out NAs
x_NA <-x[!is.na(x)] #create analyte vector w/out NAs
#create ROC variable
newROC <- rocit(score = x_NA, class = ROCtable$DSM, negref = "0", method = "non")
#create pdf
pdf(file = "~/PTY/Data/ROC Curves/ROC%03d.pdf", onefile = F, width = 7, height = 7)
#create ROC plot
plot(newROC, legend = F)
dev.off()
}
My function takes a vector (data1$IL6, data1$age, etc) as an input. Ideally, I would be able to title each plot after the input (IL6, age, etc).
Thank you ahead of time for your help
The problem is that you are opening and closing the graphics device with each plot, and the counter resets at 001 each time. You need one call to pdf(), followed by all of your calls to plot(), followed by dev.off(), like so:
# Some data with named columns
df <- data.frame(a = 1:10, b = 11:20, c = 21:30)
# A plotting function without `pdf()` and `dev.off()`
create_plot <- function(x, main) {
plot(x, main = main)
}
# Open graphics device
pdf(file = "filename-%03d.pdf", onefile = FALSE)
# Apply plotting function to each column of `df` in a loop
for (j in 1:3) {
create_plot(df[, j], names(df)[j])
}
# Close graphics device
dev.off()
This should generate filename-001.pdf, filename-002.pdf, and filename-003.pdf in your working directory.
Here is an example and the output is a png file hsa04110.gse16873.png. My question is how to get the plot displayed directly rather than save it as a file.
library(pathview)
data(gse16873.d)
data(demo.paths)
data(paths.hsa)
pathview(gene.data = gse16873.d[, 1], pathway.id = demo.paths$sel.paths[1],
species = "hsa", out.suffix = "gse16873", kegg.native = T)
#> 'select()' returned 1:1 mapping between keys and columns
#> Info: Working in directory D:/github/RNASeq-KEGG
#> Info: Writing image file hsa04110.gse16873.png
It looks like pathview only renders PNGs, so the trick is to define a function that will show the created PNG in the plot window and by default delete the file itself afterwards as if you were viewing it in memory. As an option, you can keep a copy of the PNG.
require(pathview)
require(grid)
require(png)
see_pathview <- function(..., save_image = FALSE)
{
msg <- capture.output(pathview::pathview(...), type = "message")
msg <- grep("image file", msg, value = T)
filename <- sapply(strsplit(msg, " "), function(x) x[length(x)])
img <- png::readPNG(filename)
grid::grid.raster(img)
if(!save_image) invisible(file.remove(filename))
}
Now when you do:
data(gse16873.d)
data(demo.paths)
data(paths.hsa)
see_pathview(gene.data = gse16873.d[, 1],
pathway.id = demo.paths$sel.paths[1],
species = "hsa",
out.suffix = "gse16873",
kegg.native = T)
You don't get any messages informing you about a written file, there is no new png in your working directory, and this picture pops up in the viewer pane:
I was wondering if anyone could assist with code below. I have a huge dataset (> 1000 subjects) which I'm trying to visualise individually.
I was fortunate to find a code written by Tony Cookson from R-bloggers which I've modified for my use. The code works ok but the pdfs produced are damaged-essentially they refuse to open. I have a feeling there's bug somewhere but I haven't yet figured out where. Any assistance would be highly appreciated.
library(lattice)
names = LETTERS[1:3]
for(i in 1:3){
mypath <- file.path("myFilepath", "folder containing 'Plots' subfolder ",
"Plots",paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
xyplot(conc ~ Time | Subject, group = Subject, data = Theoph, type = "l",
layout = c(2, 2), main = mytitle)
dev.off()
}
For the code to be reproducible, you need to replace myFilepath, folder containing 'Plots' subfolder and "Plots" with names of actual folders that can be found on your computer. Please see the original on R-bloggers for more details. I would be very happy to clarify anything that seems ambiguous.
Thanks
Edit:
library(lattice)
names = LETTERS[1:3]
for(i in 1:3){
mypath <- file.path("myFilepath", "folder containing 'Plots' subfolder ",
"Plots",paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
print(xyplot(conc ~ Time | Subject, group = Subject, data = Theoph, type = "l",
layout = c(2, 2), main = mytitle))
dev.off()
}
I've managed to find a temporary solution (above) using the print function. However, I'm currently getting all 12 Subjects in the same pdf. What I really want is 4 subjects (2 by 2 matrix) on separate pdfs so making 3 pdfs in total. Anyone know how to do this?
If you're looking to plot a subset of Subjects on each page, then you have to subset your data for each iteration and then plot.
To get 4 Subjects on each page, you can use the following index builder as a basis for subsetting:
(i - 1) * 4 + 1:4
The trick with the Theoph dataset is that the subject "numbers" are actually ordered factors. So you have to convert the above to a factor, or, as a shortcut, to a character vector.
for(i in 1:3){
## Changed mypath to make it reproducible
mypath <- file.path(tempdir(), paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
myIndex <- as.character((i - 1) * 4 + 1:4) # index builder from above
print(xyplot(conc ~ Time | Subject,
data = Theoph[Theoph$Subject %in% myIndex, ],
type = "l", layout = c(2, 2), main = mytitle))
dev.off()
}
The order of the subjects is a bit screwy, since that variable is an ordered factor, as mentioned. To keep the ordering, you could subset on the levels of that factor:
myIndex <- levels(Theoph$Subject)[(i - 1) * 4 + 1:4]
The best way to build your index will depend on your actual data.
I have multiple CSVs as inputs which basically have lat long info and i am exporting the .tiff images which have these lat longs plotted on a map. I want to some how loop this process so as I can read multiple CSVs and hence generate multiple maps(.tiff) corresponding to these CSVs.Any help will be appreciated !!
Here is the code which I am using at present
rm(list=ls())
sclusters_1 <- readLines("C:\\Users\\D85_H.csv")
skip_second <- sclusters_1[-2]
sclusters <- read.csv(textConnection(skip_second), header = TRUE)
library(grDevices)
library(PBSmapping)
library(maptools)
library(sp)
myShapeFile<-importShapefile("C:\\Users\\st99_d00_shp\\st99_d00",readDBF=TRUE, projection = "LL")
ConvUS <- convUL(myShapeFile)
addressEvents<-as.PolyData(sclusters,projection="LL", zone = 15)
uaddressEvents <- convUL(addressEvents)
sclusters_cl <- unique(sclusters$PID)
len <- length(sclusters_cl)
palette(c("dodgerblue3","red3","olivedrab","purple4","turquoise2","orange3","lightskyblue4","mediumorchid3","saddlebrown","skyblue4"))
setwd("C:/Users/")
name, leave .tiff extension
tiff(filename = "Test.tiff",
width = 3750, height = 3142, units = "px", pointsize = 12,
compression = "lzw",
bg = "transparent")
plotMap(ConvUS , xlim=c(-8000,3500), ylim=c(2000,9500), plt=c(0.07,0.97,0.07,0.98), bg = "white", border = "darkgrey", axes=FALSE, xlab=" ",ylab=" ", lty = 1, lwd = 2)
addPoints(uaddressEvents,col=1:len,cex=2.5, pch = "O")
legend("topright",legend = sclusters_cl, cex=0.7, fill=palette())
#close output file stream
dev.off()
Mind you, this is untested:
Since both the import and export filenames are passed as length-1 characters vectors, you can make a matrix like m <- matrix(c("infile1.csv", "outfile1.tiff", "infile2.csv", "outfile2.tiff"),nrow=2).
Then you can just wrap the entire thing in a for loop over the columns of that matrix, e.g. for(j in 1:ncol(m)). Then just replace "C:\\Users\\st99_d00_shp\\st99_d00" with m[1,j] and "Test.tiff" with m[2,j].
Even better practice might be to wrap the entire thing in a function and then write a separate loop that just calls the function. For example:
myTIFF <- function (infile, outfile) {
# stuff you want to do to each pair of input and output files
}
m <- matrix(c(
"infile1.csv", "outfile1.tiff",
"infile2.csv", "outfile2.tiff"
# and so on
), nrow = 2)
for(j in 1:ncol(m)) myTIFF(m[1, j], m[2, j])
Note also that R has function called dir that automatically extracts the contents of a directory as a character vector, in the way that ls does for variables in the current environment. If you have a large number of CSV files, you can use this (possibly in conjunction with grep) to generate the matrix m programmatically rather than typing it by hand.