Related
With this code I get the plot I want
d <- density(mydata$item1)
plot(d)
This code is the same, but omits N/As. And there is a flaw in the plot's legend. As you can see, it doesn't tell what item is plotted, (x = .)
Can you tell where is the matter and how to fix it? Thank you for your help.
My data
structure(list(item1 = c(5, 5, 5, 5, 4, 4, 2, 1, 3, 4, 4, 3,
2, 5, 2, 4, 4, 3, 6, 5, 3, 2, 5, 3, 3, 1, 3, 5, 1, 3, 2, 6, 3,
5, 4, 4, 3, 5, 6, 3, 2, 6, 6, 5, 2, 2, 2, 3, 3, 3), item2 = c(5,
4, 5, 1, 2, 2, 3, 2, 2, 2, 2, 3, 2, 5, 1, 4, 4, 3, 3, 5, 3, 2,
4, 4, 3, 4, 4, 3, 7, NA, 2, 4, 2, 4, 2, 3, 5, 3, 5, 3, 2, 6,
6, 7, 2, 3, 2, 3, 1, 4), item3 = c(5, 5, 6, 7, 3, 4, 5, 2, 2,
6, 4, 2, 5, 7, 1, 2, 4, 5, 6, 6, 5, 2, 6, 5, 6, 4, 6, 4, 6, 4,
6, 5, 5, 6, 6, 6, 5, 6, 7, 5, 5, 7, 7, 6, 2, 6, 6, 6, 5, 3)), row.names = c(NA,
-50L), class = c("tbl_df", "tbl", "data.frame"))
Use the main = argument inside plot to make the title say whatever you want it to.
Data$item2 %>%
na.omit() %>%
density() %>%
plot(main = 'Density of Data$item2')
you had a little typo in your code as the density() call was piped into a plot call refering to the variable it was been written to ... this might have resulted in the strange plot.
In general the density() function won't work with NA values acording to the documentation so you have to set the argument na.rm = TRUE as the default is FALSE for the plot to work correctly... also as #AllanCameron pointed out in an earlier answer you can set the plot title manually.
d <- density(mydata$item2, na.rm = TRUE)
plot(d)
Possibly you can substitute, interpolate or impute the NA values so that you do not have to remove them for the denstiy() call. Though this obviously depends on your data, context and goals.
I want to plot a boxplot with the regular /boxplot function of R - not ggplot.
Y and X axis are continously numeric varibales (x-axis 6 forces: 1.0, 1.3, 1.6, 2.0, 2.5, 3.1 [N])
On Y-axis the participants ratings (1 to 7).
I would like to plot it, with quantified spacing on x-axis, and also later add regression line into the plot. Cant find anything for the regular /boxplot function.
Code so far:
kraft_ou <- data.frame(VR1_100$ou_kraft,
VR1_125$ou_kraft,
VR1_160$ou_kraft,
VR1_200$ou_kraft,
VR1_250$ou_kraft,
VR1_310$ou_kraft)
colnames(kraft_ou) <- c("kraft_100", "kraft_125", "kraft_160", "kraft_200", "kraft_250", "kraft_310")
kraft_ou
boxplot(kraft_ou,
names=c("1,0 [N]", "1,3 [N]","1,6 [N]","2,0 [N]","2,5 [N]","3,1 [N]"),
col = "bisque",
ylim = c(1, 7))
points(1:6, meanskraftou, pch=4)
text(1:6, meanskraftou + 0.24, labels = meanskraftou)
abline(h=4)
data (n=30 ratings from 1 to 7 for each of the 6 forces):
dput(kraft_ou)
structure(list(kraft_100 = c(4, 3, 5, 5, 3, 4, 2, 4, 4, 5, 4,
5, 5, 4, 4, 3, 4, 4, 5, 4, 6, 5, 4, 5, 5, 5, 4, 4, 4, 4), kraft_125 = c(4,
4, 5, 6, 4, 3, 4, 4, 4, 5, 4, 5, 4, 5, 4, 3, 4, 4, 4, 6, 6, 4,
4, 5, 3, 5, 4, 4, 4, 5), kraft_160 = c(5, 6, 6, 6, 6, 4, 6, 5,
6, 5, 4, 3, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, 4, 6, 4, 5, 5,
5), kraft_200 = c(6, 5, 6, 6, 5, 4, 5, 5, 6, 7, 5, 3, 5, 5, 5,
4, 7, 6, 5, 5, 7, 6, 5, 6, 6, 6, 5, 4, 5, 3), kraft_250 = c(5,
6, 6, 7, 6, 6, 6, 6, 7, 7, 6, 5, 7, 7, 5, 5, 6, 6, 7, 7, 6, 6,
5, 5, 5, 7, 4, 6, 6, 5), kraft_310 = c(7, 7, 7, 7, 6, 5, 6, 6,
6, 7, 4, 5, 7, 6, 5, 5, 7, 6, 5, 6, 6, 6, 5, 6, 5, 6, 5, 6, 6,
6)), class = "data.frame", row.names = c(NA, -30L))
You can use the at argument to specify x locations for your boxplots, though to get them narrow enough to avoid overplotting, you need to add an invisible box and set the relative widths of the visible boxes to a smaller value:
boxplot(cbind(kraft_ou, n = rep(NA, nrow(kraft_ou))),
names=c("1,0 [N]", "1,3 [N]","1,6 [N]","2,0 [N]","2,5 [N]","3,1 [N]",
" "),
col = "bisque",
ylim = c(1, 7), width = c(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 1),
at = c(1, 1.3, 1.6, 2.0, 2.5, 3.1, 3.1))
abline(h = 4)
To add a regression line, you would need to have all your data frame values in a single y variable, and a vector of their corresponding x axis positions:
abline(lm(unlist(kraft_ou) ~ rep(c(1, 1.3, 1.6, 2.0, 2.5, 3.1), each = 30)))
I'm attempting to create a table of relative percentage values for answers to a questionnaire (answers are graded 1-5) for a total of 3 questions.
I'm using the formattable library to convert the values in the tables to percents, but thus far I am unable to combine the results for Questions 1, 2, and 3 into 1 table.
The code I have written is:
tableq1<-percent(table(Q1val)/length(na.omit(Q1val)))
tableq1
The current output is:
What do I need to do in order to achieve this?
Ultimately, I want to have this table as a pdf or png, with gridlines that make it look clean and professional.
Per request:
dput(Q1val)
c(4, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 3, 4, 5,
4, 5, 1, 5, 5, 5, 4, 5, 4, 3, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5,
5, 5, 3, 5, 5, 4, 4, 4, 4, 5, 2, 5, 4, NA, 5, 5, 5, 3, 5, 5,
4, 5, 5, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4, 5, 5, 5, 5, 5, 4, 5, 4,
4, 3, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 4, 4, 3, 5, 5, 5, 5, 4, 3,
4, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 5, 4, 4, 4, 5, 4, 4, 5, 5, 5,
5, 5, 4, 4, 5, 4, 5, 5, 5, 2, 4, 2, 5, 5, 3, 4, 3, 4, 5, 5, 4,
4, 3, 5, 5, 4, 5, 4, 3, 5, 3, 4, 4, 5, 4, 5, 5, 5, 5, 5, 5, 5,
5, 5, 4, 5, 5, 3, 3, 4, 5, 4, 5, 5 # , ...
)
In an improvement over my comments, I've chosen to render the result with the kableExtra package.
Solution
First load the appropriate packages:
library(dplyr)
library(formattable)
library(kableExtra)
Once you've generated the Q*val vectors in your workspace...
# ...
# Code to generate 'Q1val', 'Q2val', ...
# ...
...then run this workflow to consolidate them into a single contingency table:
# Identify all the 'Q*val' vectors.
q_names <- ls(pattern = "Q\\d+val")
# Assemble a single table.
q_all <- q_names %>%
# Capture those vectors in a (named) list.
mget(inherits = TRUE) %>%
# Turn each vector into a contingency table of percentages.
sapply(
FUN = function(x) {
percent(table(x) / length(na.omit(x)))
},
simplify = FALSE
) %>%
# Stack those contingency tables into a single table.
do.call(what = bind_rows) %>%
# Convert to 'data.frame' to preserve row names.
as.data.frame() %>%
# Add row names of "Q1", "Q2", ...; as extracted from the names "Q1val", "Q2val", ...
`rownames<-`(value = gsub(
x = q_names,
pattern = "^(Q\\d+)(val)$",
replacement = "\\1"
))
You can then prettify the table and export it as an image.
# Prettify the table.
q_pretty <- q_all %>%
# Convert into 'kable' object.
kbl() %>%
# Border the rows and stripe the cells.
kable_styling(
bootstrap_options = c("bordered", "striped")
# ...
# Further styling as desired.
# ...
) # %>%
# ...
# Further 'kable' adjustments as desired.
# ...
# Save pretty table as PNG image.
save_kable(
x = q_pretty,
file = "pretty.png"
)
Note
You can easily save as a PDF by replacing "pretty.png" with "pretty.pdf".
Result
I had to improvise my own Q2val and Q3val, but the resulting pretty.png should look like this:
I am wanting to plot graph clusters that I define by myself. I am using the simplified undirected enron data.
library(igraphdata)
data("enron")
g <- as.undirected(enron)
g <- simplify(g)
rm("enron")
member <- c(1, 8, 9, 9, 10, 10, 8, 7, 4, 1, 2, 6, 3, 1, 2, 8, 7, 2, 1, 5,
1, 7, 6, 4, 8, 4, 8, 10, 3, 6, 1, 4, 7, 4, 3, 7, 9, 10, 3, 8, 1,
9, 8, 2, 7, 2, 9, 5, 1, 2, 6, 10, 3, 3, 2, 1, 9, 10, 3, 5, 6, 5,
5, 3, 7, 6, 9, 10, 8, 10, 8, 8, 10, 10, 10, 8, 7, 7, 9, 1, 9, 2, 9,
7, 2, 7, 7, 3, 2, 5, 2, 1, 6, 5, 10, 4, 3, 2, 4, 6, 4, 9, 5, 4,
1, 10, 2, 3, 4, 3, 6, 3, 6, 4, 6, 8, 2, 4, 5, 1, 5, 1, 4, 10, 4, 7,
5, 9, 10, 1, 2, 1, 5, 7, 5, 3, 5, 8, 7, 9, 5, 8, 1, 5, 3, 3, 3, 10,
1, 7, 8, 4, 1, 10, 9, 6, 9, 9, 4, 2, 6, 4, 6, 3, 5, 6, 9, 7, 6, 6,
4, 8, 6, 8, 8, 2, 5, 4, 3, 2, 9, 10, 2, 7)
I have tried many ways but none looks good. The best I can make is
edges_data_frame <- get.data.frame(g, what = "edges")
w.mem <- rep(0, length(E(g)))
for (i in 1:length(E(g))){
w.mem[i] <- ifelse(member[edges_data_frame$from[i]] == member[edges_data_frame$to[i]], 500, 1)
}
mem <- make_clusters(g,member)
E(g)$weight <- w.mem
colors <- rainbow(max(membership(mem)))
layout <- layout.fruchterman.reingold(g, weights=w.mem)
set.seed(1234)
plot(g, vertex.color=colors[mem$membership],
mark.groups=communities(mem),
vertex.label = NA,
edge.width = 1, edge.color = "lightgray", vertex.size = 5)
my first trial
I found that the "deleting edges plot" looks much cleaner
coGrph <- delete_edges(g, E(g)[crossing(mem, g)])
col_vector <- c('#e6194b', '#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080', '#e6beff', '#9a6324', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1', '#000075', '#808080', '#ffffff', '#000000')
temp <- sapply(1:length(V(g)), FUN = function(i) {col_vector[member[i]]})
V(coGrph)$color <- temp
plot(coGrph, vertex.label = NA, vertex.size = 5)
my second trial
However, this plot has some missing edges and does not reflect the true connection of the plot. I want to use this plot and add the deleted edges back to the plot without changing the positions I have right now. Is it possible?
Thank you very much I really appreciate your help.
Yes. Use your coGrph to create a layout, but then plot the original graph.
Continuing your "second trial"
set.seed(1234)
LOcG = layout_nicely(coGrph)
V(g)$color <- temp
plot(g, layout=LOcG, vertex.label = NA, vertex.size = 5)
I have a list of lists where some of them are NA e.g. empty lists. I want to extract all the lists which are filled with data and remove all the lists which are empty(NA).
The code i'm trying is:
lapply(outputfile,function(x){
if(outputfile != NA){
test<-lapply(outputfile,unlist)
}})
But this does not work.
The list of lists is like this: (small example of random data)
list(NA, NA, NA, NA, NA, NA, list(c(5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5)))
I only want to extract the list with the 5s in it. The first 6 lists should be ignored e.g. removed.
Any help is appreciated
So, to remove NA at the first level, you could use is.na directly:
l[!is.na(l)]
Alternatively, you can also use Filter which tries to coerce the results of the evaluated function to logical and returns those elements that evaluated to TRUE. You could do, for example:
Filter(function(x) !is.na(x), l)
(or) equivalently (as #flodel writes under comment)
Filter(Negate(is.na), l)