print variable in a way to evaluate/use it afterwards - r

I always have a little problem, providing a little minimal working example to you at stack overflow.
Is there a way to print, for example a data frame, so I can copy and paste it into the R console again and create the same kind of variable?
so basically something like this:
awesomePrint(df)
df <- data.frame(
x = c(1, 2, 3, 4),
y = c(2, 3, 4, 5)
)

You are looking for the dput function, that prints the command you need to recreate an object.
df<-data.frame(x = c(1, 2, 3, 4),y = c(2, 3, 4, 5))
dput(df)
You can also use dump to write that line on a file or on the standard output:
dump("df","")

Related

set an argument to remove NAs in a function

I am trying to complete a function. Hopefully, sometime in the future, I may share it with other users. In this function, I would like to have an argument so that users will have an option either excluding all missing values in all analyses or as it is based on data available for different components. I wonder if there is a standard way to do this or a r rule for this.
To show my point:
mydata <- data.frame(x = c(1, 2, 3, 4, 5, NA, 7),
y = c(2, NA, 4, 5, 6, 7, NA))
myfun <- function(data, na.omit = FALSE, ...) {
if (na.omit == TRUE) {
data <- na.omit(data)
}
# computing a lot of things
print(data)
}
myfun(data = mydata, na.omit = F)
myfun(data = mydata, na.omit = T)
Although it works fine now, I am still a little worried about this because na.omit is an existing r function. Should I change this argument into something like na_omit or complete_set?

Apply an index command on a matrix of lists

I have a matrix that contains lists containing shortest path sequences of an igraph object.
I want to turn this matrix into an igraph.es(edge sequence).
sample:
library(igraph)
data <- data.frame(from =c(1, 2, 3, 4, 5, 1),
to =c(4, 3, 4, 5, 6, 5),
weight=c(0.2,0.1,0.5,0.7,0.8,0.2))
g <- graph.data.frame(data, directed=FALSE)
sp <- sapply(data, function(x){shortest_paths(g, from = x, to = V(g)[x],output = "epath")})
sp is now a matrix. We can subset it with indexing:
x<-sp[[2]][[2]]
will turn x to an igraph::edge_sequence.
I'm looking for an apply command to turn all path_sequences of sp into edge_sequences. Thank you in advance.
EDIT:
I managed to unlist the first layer of the list.
sp<-flatten(sp)
So we just need a simple index.
Can I just use a for loop now?
Something like:
for(i in sp){ result[i]<- sum(E(g)$weight[sp[[i]])}
unfortunately this doesn't give me the desired output..

How to refer to unnamed object in R

I want to perform a simple task in R. I want to call a method on an object which has not been assigned to any variable yet.
Like this:
a <- c(5, 2, 11, 3)
b <- order(a, decreasing = TRUE)[1:floor(0.1 * length(.))]
So I guess, I would like to to find, what to pass to length function here. I know that I can perform it like this:
a <- c(5, 2, 11, 3)
b <- order(a, decreasing = TRUE)
b <- b[1:floor(0.1 * length(b))]
But I wanted to make it like I wrote above.
There is as far as i know, no implemented way that will achieve higher efficiency than the base code
a <- c(5, 2, 11, 3)
b <- order(a, decreasing = TRUE)
b[1:floor(0.1 * length(b))]
However one can achieve something similar to what you are asking, using either the magrittr, the dplyr or similar packages, which allow for piping calls. This would look similar to
a <- c(5, 2, 11, 3)
c <- a %>% order(., decreasing = TRUE) %>% .[1:floor(0.1 * length(.))]
identical(b[1:floor(0.1 * length(b))],c)
[1] TRUE

How to create chain from pairs in R

edit: added current solution
I am dabbling with the Travelling Salesman Problem and am using a solver to calculate the most optimal tour. The output of my linear solver gives me a table with arches in a route, however to plot the tour I require vector with all the locations chained in the right order. Is there an elegant way to chain these arches into a single tour?
One solution would be a series of (nested) joins/matches, however that is not an elegant solution in my opinion.
# output of solver (where i = 'from' and j = 'to')
solution = data.frame(i = c(6, 4, 10, 7, 1, 9, 3, 2, 8, 5),
j = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
# transformation
??
# required output
tour = c(6, 1, 5, 10, 3, 7, 4, 2, 8, 9)
So the output I am looking for is a single chain of connected arches (from i to j) in the tour.
My current solution uses for loops and match and looks as follows:
# number of cities to visit
nCities = length(solution)
# empty matrix
tour = matrix(0, nCities, 2)
#first location to visit picked manually
tour[1, ] = solution[1, ]
# for loop to find index of next arch in tour
for(k in 2:nCities){
ind = match(tour[k - 1, 2], solution[, 1])
tour[k, ] = solution[ind, ]
}
# output 'tour' is the solution but then sorted.
# I then take only the first column which is the tour
tour = tour[1, ]
However, it looks clunky and as I try to avoid for loops as much as possible I am not to happy with it. Also, my suspicion is that there are more elegant solutions out there, preferably using base R functions.

Re-ordering bars in R's barplot()

What I want to achieve is exactly the same that was already asked here (and specifically using R's base graphics, not packages like ggplot or lattice): Ordering bars in barplot()
However, the solutions proposed there do not seem to work for me. What I need to is the following. Suppose I have this:
num <- c(1, 8, 4, 3, 6, 7, 5, 2, 11, 3)
cat <- c(letters[1:length(num)])
data <- data.frame(num, cat)
If I generate a barplot using barplot(data$num), here is what I get:
Now, I want to reorder the bars according to data$cat. Following the link I mentioned above, I tried the accepted answer but got an error:
num2 <- factor(num, labels = as.character(cat))
Error in factor(num, labels = as.character(cat)) : invalid 'labels'; length 10 should be 1 or 9
Then I also tried the other answer there:
num <- as.factor(num)
barplot(table(num))
But here is what I got:
So, in this particular case of mine, which is slightly different from that question, how should I order the barplot so the bars are defined by data$num but ordered according to data$cat?
you can use ggplot to do this
library("ggplot2")
num <- c(1, 8, 4, 3, 6, 7, 5, 2, 11, 3)
cat <- c(letters[1:10])
data <- data.frame(num, cat)
ggplot(data,aes(x= reorder(cat,-num),num))+geom_bar(stat ="identity")
The result is as shown below
Using base functions
df <- data[order(data$num,decreasing = TRUE),]
barplot(df$num,names.arg = df$cat)
I get the following,
num <- c(1, 8, 4, 3, 6, 7, 5, 2, 11, 3)
cat <- c(letters[1:10])
data <- data.frame(num, cat)
barplot(data[order(data[,1],decreasing=TRUE),][,1],names.arg=data[order(data[,1],decreasing=TRUE),][,2])
The above code uses the order() function twice (see comments, below). To avoid doing this the results of the ordered data.frame can be stored in a new data.frame and this can be used to generate the barplot.
num <- c(1, 8, 4, 3, 6, 7, 5, 2, 11, 3)
cat <- c(letters[1:10])
data <- data.frame(num, cat)
data2 <- data[order(data[,1],decreasing=TRUE),]
barplot(data2[,1],names.arg=data2[,2])
Alternatively, you can also use the following if you don't want to put your data in a new dataframe. Just a little simpler.
barplot(sort(data$num, decreasing = TRUE))

Resources