set factor level in ggplot2 - r

Hello I would need help in order to sort geom_segment in my plot by the column end_scaffold.
Here is the code I used to produce the following plot :
library(ggplot2)
#Here I try to sort the data in order to get geom_segment sorted in the plot but it does not work
tab<-tab[with(tab, order(-end_scaff,-end_gene)), ]
ggplot(tab, aes(x = start_scaff, xend = end_scaff,
y = molecule, yend = molecule)) +
geom_segment(size = 3, col = "grey80") +
geom_segment(aes(x = ifelse(direction == 1, start_gene, end_gene),
xend = ifelse(direction == 1, end_gene, start_gene)),
data = tab,
arrow = arrow(length = unit(0.1, "inches")), size = 2) +
geom_text(aes(x = start_gene, y = molecule, label = gene),
data = tab, nudge_y = 0.2) +
scale_y_discrete(limits = rev(levels(tab$molecule))) +
theme_minimal()
does someone have an idea in order to sort the geom_segment by the column end_scaffold (descending) (where scaffold_1254 should be on the top of the plot and scaffold_74038 shoudl be on the bottom).
here are the data
> dput(tab)
structure(list(molecule = structure(c(2L, 6L, 6L, 3L, 7L, 4L,
5L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L), .Label = c("", "scaffold_1254", "scaffold_15158", "scaffold_7180",
"scaffold_74038", "scaffold_7638", "scaffold_8315"), class = "factor"),
gene = structure(c(8L, 6L, 5L, 3L, 7L, 4L, 2L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("",
"G1", "G2", "G3", "G4", "G5", "G6", "G7"), class = "factor"),
start_gene = c(6708L, 9567L, 3456L, 10105L, 2760L, 9814L,
1476L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA), end_gene = c(11967L, 10665L, 4479L, 10609L,
3849L, 10132L, 2010L, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA), start_scaff = c(1L, 1L,
1L, 1L, 1L, 1L, 1L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA), end_scaff = c(20072, 15336,
15336, 13487, 10827, 10155, 2010, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), strand = structure(c(2L,
2L, 3L, 2L, 3L, 2L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("", "backward",
"forward"), class = "factor"), direction = c(-1L, -1L, 1L,
-1L, 1L, -1L, 1L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA)), row.names = c(7L, 5L, 4L, 2L,
6L, 3L, 1L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L,
19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L,
32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L), class = "data.frame")

For a solution inside ggplot you can remove the limits to the scale_y_discrete (it would reorder based on the factor levels) and use y = reorder(molecule, end_scaff) inside the aes:
library(dplyr)
library(ggplot2)
tab <- tab %>% filter(!is.na(start_gene))
ggplot(tab, aes(x = start_scaff, xend = end_scaff,
y = reorder(molecule, end_scaff), yend = molecule)) +
geom_segment(size = 3, col = "grey80") +
geom_segment(aes(x = ifelse(direction == 1, start_gene, end_gene),xend = ifelse(direction == 1, end_gene, start_gene)),
arrow = arrow(length = unit(0.1, "inches")), size = 2) +
geom_text(aes(x = start_gene, y = molecule, label = gene), nudge_y = 0.2) +
scale_y_discrete() +
theme_minimal()
Created on 2020-09-04 by the reprex package (v0.3.0)

The trick is to reorder the levels of molecule, not the entire data.frame. Instead of
tab <- tab[with(tab, order(-end_scaff,-end_gene)), ]
run
i <- with(tab, order(-end_scaff,-end_gene))
mol <- unique(tab$molecule[i])
tab$molecule <- factor(tab$molecule, levels = mol)
The same plotting code now produces the following graph.

Related

Convert multiple columns from numeric to factor

I thought this task is simple, then I was surprised that it wasn't.
I have multiple selected columns with coded responses (likert-scales). I want to transform them into a factor variable with factor levels (some of them were never chosen). The questionnair is in German, that is why I you probably won't be able to understand the labels.
df[,c(3:21,23:25)] <- apply(df[,c(3:21,23:25)],2,
function (x) factor(x,
levels = c(0,1,2,3,4),
labels = c("gar nicht",
"gering",
"eher schwach",
"eher stark",
"sehr stark")))
df[,22] <- apply(df[,22],1,
function (x) factor(x,
levels = c(0,1,2,3),
labels = c("gar nicht",
"sofort",
"mittelfristig",
"langfristig")))
I will need to split those data frames because of the different scales. Nevertheless,
it does not transform my data accurately. The outcome is a character.
Here is my test data:
structure(list(ï..lfdNr = 1:20, company = c("Nationalpark Thayathal",
"Naturpark Heidenreichsteiner Moor", "Naturpark Hohe Wand", "Tierpark Stadt Haag",
"Ötscher Tropfsteinhöhle", "Carnuntum", "Stift Heiligenkreuz",
"Ruine Kollmitz", "Schlosshof", "Retzer Erlebniskeller", "LOISIUM Weinwelt",
"Bio Imkerei Stögerer", "Amethyst Welt Maissau", "Donau Niederösterreich tourismus",
"Niederösterreich Bahnen", "Benediktinerstift Melk", "Kunstmeile Krems",
"Die Garten Tulln", "Winzer Krems ", "Domäne Wachau"), A2_1_hitz = c(4L,
NA, NA, 3L, NA, NA, 3L, 2L, 3L, NA, 3L, NA, 3L, NA, 2L, 3L, 3L,
4L, 2L, 3L), A2_2_trock = c(3L, NA, NA, 3L, NA, NA, 3L, NA, 3L,
NA, 2L, NA, 1L, NA, 2L, 4L, 3L, 4L, 2L, 3L), A2_3_reg = c(2L,
NA, NA, 2L, NA, NA, 3L, 2L, 3L, NA, 3L, NA, 2L, NA, 3L, 4L, 2L,
3L, 4L, 2L), A2_4_schnee = c(4L, NA, NA, 3L, NA, NA, NA, 3L,
3L, NA, 1L, NA, 0L, NA, 4L, NA, 3L, 4L, 4L, 1L), B1_1_hitz = c(4L,
NA, NA, 1L, NA, NA, NA, 3L, 3L, NA, 2L, NA, NA, NA, 2L, 3L, 2L,
4L, 0L, 2L), B1_2_trock = c(3L, NA, NA, 2L, NA, NA, NA, NA, 3L,
NA, 0L, NA, NA, NA, 2L, 3L, 2L, 4L, 3L, 1L), B1_3_reg = c(2L,
NA, NA, 1L, NA, NA, NA, NA, 3L, NA, 3L, NA, NA, NA, 3L, 3L, 1L,
2L, 3L, 3L), B1_4_schnee = c(1L, NA, NA, 0L, NA, NA, 0L, 0L,
1L, NA, NA, NA, NA, NA, 4L, 1L, 0L, 4L, 0L, 0L), B2_1_nZuk = c(3L,
NA, NA, 0L, NA, NA, NA, 0L, 0L, NA, 0L, NA, 0L, 3L, 3L, 0L, 3L,
2L, 0L, 0L), B2_2_mZuk = c(3L, NA, NA, 0L, NA, NA, NA, 0L, 2L,
NA, 2L, NA, 0L, 2L, 3L, 0L, 3L, 2L, 3L, 0L), B2_3_fZuk = c(3L,
NA, NA, 2L, NA, NA, NA, NA, 2L, NA, 2L, NA, 0L, 2L, 3L, 0L, 3L,
NA, 3L, 0L), C1_1_aktEin = c(2L, NA, NA, 1L, NA, NA, NA, NA,
2L, NA, NA, NA, NA, NA, NA, 0L, 1L, 3L, 2L, 3L), C1_2_zukEin = c(3L,
NA, NA, 2L, NA, NA, NA, NA, 3L, NA, NA, NA, NA, NA, NA, 0L, 2L,
4L, 3L, 3L), C2_1_bisVer = c(2L, NA, NA, 1L, NA, NA, NA, NA,
2L, NA, NA, NA, NA, NA, 2L, 2L, 1L, 3L, 2L, 2L), C2_2_zukVer = c(3L,
NA, NA, 2L, NA, NA, NA, NA, 3L, NA, NA, NA, NA, NA, 2L, 2L, 2L,
3L, 3L, 2L), C3_1_bisVer = c(NA, NA, NA, 1L, NA, NA, 2L, NA,
3L, NA, NA, NA, NA, NA, 1L, 1L, 1L, NA, 2L, 2L), C3_2_zukVer = c(NA,
NA, NA, 2L, NA, NA, 3L, NA, 3L, NA, NA, NA, NA, NA, 1L, 2L, 2L,
NA, 3L, 2L), C4_1_EinKlim = c(NA, NA, NA, 2L, NA, NA, NA, NA,
2L, NA, 2L, NA, NA, NA, 3L, 0L, 1L, NA, 3L, 1L), D1a_1_StÃ.rke = c(NA,
NA, NA, 3L, NA, NA, NA, NA, 3L, NA, NA, NA, 3L, NA, 2L, 3L, 2L,
3L, 3L, 3L), D1b_1_Dring = c(NA, NA, NA, NA, NA, NA, 2L, 3L,
NA, NA, NA, NA, 2L, NA, 1L, 1L, 1L, 1L, 1L, 1L), D5_1_bestBed = c(NA,
NA, NA, 0L, NA, NA, NA, NA, 3L, NA, NA, NA, NA, NA, NA, 2L, 1L,
NA, 3L, 3L), E1_1_zuBesuch = c(NA, NA, NA, 2L, NA, NA, NA, NA,
3L, NA, NA, NA, NA, NA, 4L, 1L, 4L, NA, 4L, NA), E1_2_wirtBed = c(NA,
NA, NA, 3L, NA, NA, 3L, NA, 2L, NA, NA, NA, NA, NA, 1L, 1L, 4L,
NA, 3L, NA)), row.names = c(NA, 20L), class = "data.frame")
Thanks,
nadine
We need lapply and not apply as apply converts to matrix and matrix can have only a single class
df[,c(3:21,23:25)] <- lapply(df[,c(3:21,23:25)],
function (x) factor(x,
levels = c(0,1,2,3),
labels = c("gar nicht",
"sofort",
"mittelfristig",
"langfristig")))

Label single bars in ggplot

I wonder how it would be possible to add labels to single bars in ggplot2 as I would like to label my rows in my barplot as Online Broker, Bank, No Account. Thank you for your help!
Here is my code:
library(gridExtra)
library(ggplot2)
require(gridExtra)
library(tidyverse)
library (scales)
plot1 <- ggplot(data = df, aes(df$InvA, y = after_stat(prop)), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ggtitle("Post-Covid") +
xlab("Accounts") +
ylab("Individuals") +
scale_y_continuous(labels = percent_format(), limits=c(0,0.8))
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
plot2 <- ggplot(data = df, aes(df$InvAcc, y = after_stat(prop)), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ggtitle("Pre-Covid") +
xlab("Accounts") +
ylab("Individuals") +
scale_y_continuous(labels = percent_format(), limits=c(0,0.8))
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
grid.arrange(plot2, plot1, ncol = 2)
The plot then looks like this:
However, the labels should look like these for my previous plot, but since I managed to get the y-scale to percent, my labels disappeared or it doesn't work to compute the y-scale to percent with the values remaining as factors (Online-Broker, Bank, No-Account) since I had to change them to numeric (1,2,3):
dput(dfaccounts) # (with 1=Online Broker, 2=Bank, 3=No Account)
structure(list(df.InvAcc = c(2L, NA, 2L, NA, NA, 3L, 3L, 3L,
NA, 3L, 3L, NA, 1L, NA, 1L, NA, NA, 1L, NA, NA, NA, 1L, 3L, 1L,
NA, NA, 1L, 2L, NA, NA, 1L, 1L, 1L, 1L, 1L, 1L, 1L, NA, 2L, NA,
NA, 3L, NA, NA, 1L, NA, 2L, NA, NA, NA, NA, NA, NA, NA, NA, 1L,
1L, 1L, 1L, NA, NA, NA, 3L, NA, 1L, NA, NA, 2L, NA, 1L, 1L, 1L,
NA, 1L, 3L, NA, 1L, NA, 3L, NA, NA, 2L, 3L, 2L, 1L, NA, 3L, 2L,
NA, NA, 3L, NA, 2L, 1L, NA, 3L, 2L, 1L, 3L, 3L, 3L, NA, 3L, NA,
3L, NA, 3L, 1L, NA, NA, NA, 1L, NA, NA, NA, 1L, NA, NA, 3L, NA,
NA, 3L, 3L, 3L, 3L, NA, 1L, NA, NA, NA, 3L, NA, 3L), df.InvA = c(NA,
1L, NA, 2L, 1L, NA, NA, NA, 3L, NA, NA, 3L, NA, 3L, NA, 1L, 2L,
NA, 1L, 1L, 1L, NA, NA, NA, 1L, 2L, NA, NA, 2L, 1L, NA, NA, NA,
NA, NA, NA, NA, 3L, NA, 1L, 1L, NA, 1L, 1L, NA, 1L, NA, 1L, 3L,
1L, 1L, 1L, 2L, 1L, 1L, NA, NA, NA, NA, 1L, 1L, 1L, NA, 2L, NA,
2L, 1L, NA, 2L, NA, NA, NA, 2L, NA, NA, 2L, NA, 1L, NA, 3L, 3L,
NA, NA, NA, NA, 1L, NA, NA, 1L, 2L, NA, 1L, NA, NA, 1L, NA, NA,
NA, NA, NA, NA, 1L, NA, 1L, NA, 1L, NA, NA, 1L, 1L, 3L, NA, 1L,
2L, 2L, NA, 1L, 1L, NA, 3L, 1L, NA, NA, NA, NA, 1L, NA, 1L, 3L,
1L, NA, 3L, NA)), class = "data.frame", row.names = c(NA, -133L
))
The issue is that you InvA and InvAcc columns are numerics. Hence, using scale_x_discrete the axis text gets dropped.
To fix you issue I would suggest to convert the columns to factors with your desired labels set via the labels argument. Additionally, to get the right percentages we have to explicitly set the group aes via group=1:
library(gridExtra)
library(ggplot2)
labels <- c("Online-Broker", "Bank", "No Account")
data$InvA <- factor(data$InvA, labels = labels)
data$InvAcc <- factor(data$InvAcc, labels = labels)
plot1 <- ggplot(data = data, aes(InvA, y = after_stat(prop), group = 1), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ylim(0, 40) +
ggtitle("Post-Covid") +
xlab("Accounts") +
ylab("Total No. of Individuals") +
scale_y_continuous(labels = scales::percent)
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
plot2 <- ggplot(data = data, aes(InvAcc, y = after_stat(prop), group = 1), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ylim(0, 40) +
ggtitle("Pre-Covid") +
xlab("Accounts") +
ylab("Total No. of Individuals") +
scale_y_continuous(labels = scales::percent)
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
grid.arrange(plot2, plot1, ncol = 2)
#> Warning: Removed 64 rows containing non-finite values (stat_count).
#> Warning: Removed 69 rows containing non-finite values (stat_count).

y -axis scale as percent in ggplot

I read already through all the other similar questions & answers, but all the given solutions with scale_y_continous simply don't work for my dataset. I have two different treatment groups data$InvA (Post-Covid) and data$InvAcc (Pre-Covid) where in each group they could choose between the options: Online Broker (1), Bank (2), No Account (3). As the subjects were put randomly in group 1 or 2, I have logically a lot of NA's in my dataset. Now when I use ggplot, I'm able to display both results with the total number of individuals on the y-axis. However, I would like to change this to percent, since it would be a better fit for my thesis. I tried already every other option with scale_y_continuous but it rather doesn't work out properly (3000% percentage, or it doesn't calculate the right percent values) or it doesn't work at all.
This is my code:
library(gridExtra)
library(ggplot2)
require(gridExtra)
library(tidyverse)
plot1 <- ggplot(data = data, aes(InvA), na.rm=TRUE) +
geom_bar()+
scale_x_discrete(na.translate = FALSE)+
ylim(0,40)+
ggtitle("Post-Covid")+
xlab("Accounts")+
ylab("Total No. of Individuals")
plot2 <- ggplot(data = data, aes(InvAcc), na.rm=TRUE) +
geom_bar()+
scale_x_discrete(na.translate = FALSE)+
ylim(0,40)+
ggtitle("Pre-Covid")+
xlab("Accounts")+
ylab("Total No. of Individuals")
grid.arrange(plot2, plot1,ncol=2) # Write the grid.arrange in the file
#dev.off() # Close the file
#pdf("Accountss.pdf", width = 8, height = 6) # Open a new pdf file
My data:
dput(data)
structure(list(data.InvAcc = c(2L, NA, 2L, NA, NA, 3L, 3L, 3L,
NA, 3L, 3L, NA, 1L, NA, 1L, NA, NA, 1L, NA, NA, NA, 1L, 3L, 1L,
NA, NA, 1L, 2L, NA, NA, 1L, 1L, 1L, 1L, 1L, 1L, 1L, NA, 2L, NA,
NA, 3L, NA, NA, 1L, NA, 2L, NA, NA, NA, NA, NA, NA, NA, NA, 1L,
1L, 1L, 1L, NA, NA, NA, 3L, NA, 1L, NA, NA, 2L, NA, 1L, 1L, 1L,
NA, 1L, 3L, NA, 1L, NA, 3L, NA, NA, 2L, 3L, 2L, 1L, NA, 3L, 2L,
NA, NA, 3L, NA, 2L, 1L, NA, 3L, 2L, 1L, 3L, 3L, 3L, NA, 3L, NA,
3L, NA, 3L, 1L, NA, NA, NA, 1L, NA, NA, NA, 1L, NA, NA, 3L, NA,
NA, 3L, 3L, 3L, 3L, NA, 1L, NA, NA, NA, 3L, NA, 3L), data.InvA = c(NA,
1L, NA, 2L, 1L, NA, NA, NA, 3L, NA, NA, 3L, NA, 3L, NA, 1L, 2L,
NA, 1L, 1L, 1L, NA, NA, NA, 1L, 2L, NA, NA, 2L, 1L, NA, NA, NA,
NA, NA, NA, NA, 3L, NA, 1L, 1L, NA, 1L, 1L, NA, 1L, NA, 1L, 3L,
1L, 1L, 1L, 2L, 1L, 1L, NA, NA, NA, NA, 1L, 1L, 1L, NA, 2L, NA,
2L, 1L, NA, 2L, NA, NA, NA, 2L, NA, NA, 2L, NA, 1L, NA, 3L, 3L,
NA, NA, NA, NA, 1L, NA, NA, 1L, 2L, NA, 1L, NA, NA, 1L, NA, NA,
NA, NA, NA, NA, 1L, NA, 1L, NA, 1L, NA, NA, 1L, 1L, 3L, NA, 1L,
2L, 2L, NA, 1L, 1L, NA, 3L, 1L, NA, NA, NA, NA, 1L, NA, 1L, 3L,
1L, NA, 3L, NA)), class = "data.frame", row.names = c(NA, -133L
))
data$InvAcc: Online Broker --> 31 (45%), Bank --> 11 (16%), No Account --> 27(39%)
data$InvA: Online Broker --> 40 (63%), Bank --> 13 (20%), No Account --> 11(17%)
Thank you all for your help, appreciate your time!
The issue is that you are plotting the counts. If you want to plot the percentages than you have to tell ggplot to do so using e.g. y = after_stat(prop) which instead of the counts will map the proportions on y. Afterwards you could get petrcent labels using scales::percent:
library(gridExtra)
library(ggplot2)
plot1 <- ggplot(data = data, aes(InvA, y = after_stat(prop)), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ylim(0, 40) +
ggtitle("Post-Covid") +
xlab("Accounts") +
ylab("Total No. of Individuals") +
scale_y_continuous(labels = scales::percent)
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
plot2 <- ggplot(data = data, aes(InvAcc, y = after_stat(prop)), na.rm = TRUE) +
geom_bar() +
scale_x_discrete(na.translate = FALSE) +
ylim(0, 40) +
ggtitle("Pre-Covid") +
xlab("Accounts") +
ylab("Total No. of Individuals") +
scale_y_continuous(labels = scales::percent)
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
grid.arrange(plot2, plot1, ncol = 2)
#> Warning: Removed 64 rows containing non-finite values (stat_count).
#> Warning: Removed 69 rows containing non-finite values (stat_count).

join two dataframes with marking of cell by color when write.xlsx in R

i have two dataframes
prop=structure(list(KOD_NAR.id = structure(c(1L, 1L, 2L, 9L, 15L,
16L, 17L, 3L, 4L, 18L, 5L, 6L, 19L, 20L, 7L, 8L, 21L, 10L, 11L,
12L, 13L, 14L), .Label = c("", "-1", "04А ", "04Б ", "05А ",
"05Б ", "07Д ", "07С ", "1", "10", "11", "12Г ", "13", "15",
"2", "3", "4", "5", "6", "7", "9"), class = "factor"), X1000494 = structure(c(4L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 3L), .Label = c("", "0.00425531914893617", "0.0106382978723404",
"0.848936170212766"), class = "factor"), X1000495 = structure(c(4L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 3L), .Label = c("", "0.00651465798045603", "0.0293159609120521",
"0.892508143322475"), class = "factor"), X1000496 = structure(c(4L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
1L, 1L, 1L, 1L, 3L), .Label = c("", "0.00366300366300366", "0.0366300366300366",
"0.835164835164835"), class = "factor"), X1000500 = structure(c(3L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 2L), .Label = c("", "0.0161290322580645", "1.09032258064516"
), class = "factor")), .Names = c("KOD_NAR.id", "X1000494", "X1000495",
"X1000496", "X1000500"), class = "data.frame", row.names = c(NA,
-22L))
The second
mash=structure(list(KOD_NAR.id = structure(c(1L, 8L, 16L, 17L, 18L,
2L, 3L, 19L, 4L, 5L, 20L, 21L, 6L, 7L, 22L, 9L, 10L, 11L, 12L,
13L, 14L, 15L), .Label = c("-1", "04А ", "04Б ", "05А ", "05Б ",
"07Д ", "07С ", "1", "10", "11", "12Г ", "13", "15", "16",
"16А ", "2", "3", "4", "5", "6", "7", "9"), class = "factor"),
X1000494 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, 0L, 0L, NA), X1000495 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, 1L, 1L, NA), X1000496 = c(NA, NA, NA, NA, NA,
NA, NA, 0L, NA, NA, NA, NA, NA, NA, 0L, NA, NA, NA, NA, 2L,
0L, NA), X1000500 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0L, 0L, NA)), .Names = c("KOD_NAR.id",
"X1000494", "X1000495", "X1000496", "X1000500"), class = "data.frame", row.names = c(NA,
-22L))
i want merge these dataframes but in a special way, namely:
the file structure is such that by the rows the error's code of the driver, and by the columns the driver's ID.
How can i join to the metric data of prop dataframe the nominal data of mash dataframe by corresponding KOD_NAR.id. and then after joining load excel file( write.xlsx) with marked cells by color . If in the cell in brackets 0, then color is green, if 1, then color is yellow, if 2, then color of cells is red
So output:
is there way to do it?
I'm sure there are more elegant ways to do it (I'm bad with apply), but this one works.
There was a little problem with the datasets you provided
library(openxlsx)
library(tidyr)
style0=createStyle(fgFill = "green") #here you can change colors
style1=createStyle(fgFill = "yellow")
style2=createStyle(fgFill = "red")
prop$KOD_NAR.id=as.character(prop$KOD_NAR.id)
prop$KOD_NAR.id[1:2]=c("16","16a") #there must have been something wrong with the data, these two codes found in mash are not in prop
prop$KOD_NAR.id=factor(prop$KOD_NAR.id)
mash_long=mash %>% gather(key="ID",value="mash",-KOD_NAR.id)
prop_long=prop %>% gather(key="ID",value="prop",-KOD_NAR.id)
df=full_join(mash_long,prop_long) # KOD_NAR.id in prop had empty cells
df$mash[is.na(df$mash)]=""
df$prop[is.na(df$prop)]=""
df$cellcontent=ifelse(df$mash=="",df$prop,paste0(df$prop," (",df$mash,")"))
df_write=df %>% select(ID,cellcontent,KOD_NAR.id,starts_with("X")) %>% spread(ID,cellcontent)
wb=createWorkbook("workbook")
addWorksheet(wb,"Info")
writeData(wb,sheet = 1,df_write)
for(i in 2:ncol(df_write)){
for(k in 1:nrow(df_write)){
if(grepl("\\(",df_write[k,i])){
addStyle(wb=wb,sheet = 1,rows = k+1,cols = i, #there will be a header row
style=get(paste0("style",gsub(".*\\((\\d+)\\)","\\1",df_write[k,i]))))
}
}
}
saveWorkbook(wb,"example.xlsx",overwrite = T)

Copy and insert row (with a minor change) in dataframe ABOVE a variable

I'm really new to R, and struggling with the following. If anyone could suggest where I look for a solution or point me in the right direction, I'd be forever grateful.
I have a dataset where I'd like to copy a row and insert that copy with an amendment (in this case appending ", USA) into the same dataframe when it find a value in the second column (a before and after dput are below).
I can find examples of duplicating row based on a regular pattern (ie. copy and insert every fourth row), but I'm not sure how I'd do that if the pattern isn't regular.
Any help would be greatly appreciated.
before = structure(list(Teams = structure(c(4L, 1L, 1L, 2L, 1L, 1L, 1L,
5L, 1L, 1L, 3L, 1L, 1L, 1L, 1L), .Label = c("", "Blue", "Green",
"Red", "Yellow"), class = "factor"), City = structure(c(1L, 2L,
1L, 1L, 4L, 1L, 1L, 1L, 5L, 1L, 1L, 3L, 1L, 1L, 1L), .Label = c("",
"California", "Chicago", "New York ", "Ohio"), class = "factor"),
Jan = c(NA, NA, 156.156, NA, NA, 818.87, 1586.4, NA, NA,
87.1, NA, NA, 873.4, 41.1, 1886.5), Feb = c(NA, NA, 1856,
NA, NA, 17.1, NA, NA, NA, NA, NA, NA, 48.8, NA, 187)), class = "data.frame", row.names = c(NA,
-15L))
after = structure(list(Teams = structure(c(4L, 1L, 1L, 1L, 2L, 1L, 1L,
1L, 1L, 5L, 1L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 1L), .Label = c("",
"Blue", "Green", "Red", "Yellow"), class = "factor"), City = structure(c(1L,
3L, 2L, 1L, 1L, 7L, 6L, 1L, 1L, 1L, 9L, 8L, 1L, 1L, 5L, 4L, 1L,
1L, 1L), .Label = c("", "California", "California, USA", "Chicago",
"Chicago, USA", "New York", "New York, USA", "Ohio", "Ohio, USA"
), class = "factor"), Jan = c(NA, NA, NA, 156.156, NA, NA, NA,
818.87, 1586.4, NA, NA, NA, 87.1, NA, NA, NA, 873.4, 41.1, 1886.5
), Feb = c(NA, NA, NA, 1856, NA, NA, NA, 17.1, NA, NA, NA, NA,
NA, NA, NA, NA, 48.8, NA, 187)), class = "data.frame", row.names = c(NA,
-19L))
will this work for you?
library(dplyr)
before %>% mutate(City = ifelse(City != "", paste0(City, ", USA"), ""))
Basically, you consider working around columns.
You can also use base R, which is more cumbersome. You need to convert your City to character first.
before$City = as.character(before$City)
before[before[, 2] != "", 2] = paste0(before[before[, 2] != "", 2], ",USA")
Edits:
I don't have an elegant way. This is an ugly for loop solution.
before$City = as.character(before$City)
df=NULL
for(i in 1:nrow(before)){
df=rbind(df,before[i,])
if(before[i,2]!=""){
before[i,2]=paste0(before[i,2], ",USA")
df=rbind(df,before[i,])
}
}
df

Resources