I would like to give a little informative message about where I am in the for-loop.
So I have this snippet of code:
for (i in 1:20) {
dashes = paste0(replicate(20, "-"), collapse = "")
cat("This should be above and not change")
cat(paste0("\r", i, " ", dashes))
Sys.sleep(0.3)
}
However, the output in the console looks like this:
9 --------------------This should be above and not change
While the number updates in place (which is the behavior I wanted), the "This should...", should be placed above and not move at all. I tried a couple of things but did not really succeed in doing so.
Not a very good question...
This simple if does the trick.
for (i in 1:20) {
dashes = paste0(replicate(20, "-"), collapse = "")
if (i == 1) {
cat("This should be above and not change\n")
}
cat(paste0("\r", i, " ", dashes))
Sys.sleep(0.3)
}
Related
I don't get any error but I was expecting that when I type an integer that is not 1,2,3,4 the code should enter in else statement and print what is in paste0 function. What is wrong?
escolha <- as.integer(readline(prompt="Enter your choice: "))
if(escolha == 1){
print("Cool you choose addition!")
} else if (escolha == 2) {
print("Cool, you choose subtraction!")
} else if (escolha == 3) {
print("Cool, you choose multiplication!")
} else if (escolha == 4){
print("Cool, you choose division!")
} else{
paste0("It's not possible to use ", escolha," as input.")
escolha<- as.integer(readline(prompt="Choose a valid number (1 a 4): "))
}
num1 <- as.double(readline(prompt="What is the first number? "))
num2 <- as.double(readline(prompt="What is the second number? "))
resultado <- switch (escolha, (num1+num2), (num1-num2), (num1*num2), (num1/num2))
cat("The result is: ", resultado)
paste0() (and paste()) assemble a string and return it. You still need to print the result to the screen with print() or cat(), like this:
cat(paste0("It's not possible to use ", escolha," as input.\n"))
(added the \n at the end, so the readline() prompt that follows will be on a separate line)
I am working on optimizing job orders, with a precedence matrix.
For example; job 8 cannot be performed before job 6 is finished. If this is the case, my precedence matrix on position [8,6] shows a one. If there is no precedence relation, for example for position [1,2], then it shows a zero.
In my current code I use the 'next' command to go to the next iteration if the precedence matrix shows a 1. However, the way it is programmed right now it just goes to the next j, while I want it to go to the next 'i' (next job to consider). However, the i is one loop before the if loop where 'next' is used. Is there a way to make it go to the for(i in n:jobs) loop instead of the next for(j in n:jobs)?
Below my current code
# Initialisatie
nJobs = 10
jobDone = rep(FALSE, nJobs)
currentJob = 1;
jobDone[currentJob] = TRUE;
totalFine = 0;
finishingTime = durations[currentProject]
jobOrder = c(currentJob);
jobFines = c(totalFine);
jobIndFines = c(totalFine)
jobTimes = c(finishingTime)
jobIndTimes = c(durations[currentJob])
for(iter in 1:(nJobs-1))
{
bestFine = -1;
bestOrder = -1;
for(i in 1:nJobs)
{
for(j in 1:nJobs){
if(precedences[i,j] == 1){ next } #hoe kom ik nu naar de volgende i ipv de volgende j?
else{
if( ! jobDone[i] )
{
# If this is the first option or the cheapest option, we update the best option
if(bestOrder == -1 || ((finishingTime+durations[i])-deadlines[i])*fines[i] > bestFine)
{
bestFine = ((finishingTime+durations[i])-deadlines[i])*fines[i];
bestOrder = i;
}
}
}
}
}
# Add the best job to the order of jobs
jobDone[bestOrder] = TRUE;
jobOrder[iter+1] = bestOrder;
# Update the current order of projects
fine = ((finishingTime+durations[bestOrder])-deadlines[bestOrder])*fines[bestOrder]
jobIndFines[iter+1] = fine
if (fine>0){
totalFine = totalFine + fine;
}
jobFines[iter+1] = totalFine;
#jobIndFines[iter+1] = totalFine - jobFines[iter];
finishingTime = finishingTime + durations[bestOrder];
jobTimes[iter+1] = finishingTime
jobIndTimes[iter+1] = durations[bestOrder]
}
totalFine
finishingTime
jobOrder
jobFines
jobTimes
jobIndTimes
jobDone
jobIndFines
Thanks a lot!!
Try break.
These code snippets illustrate the difference between next and break.
next restarts the current loop at its next index value:
for (i in 1:2) {
for (j in 1:2) {
print(paste("j =", j))
next
print("Python is better than R at everything.") # Never prints, obviously.
}
print(paste("i =", i))
}
#> [1] "j = 1"
#> [1] "j = 2"
#> [1] "i = 1"
#> [1] "j = 1"
#> [1] "j = 2"
#> [1] "i = 2"
break gets you out of the current loop entirely and passes control to the next statement outside the loop:
for (i in 1:2) {
for (j in 1:2) {
print(paste("j =", j))
break
print("Python is better than R at everything.") # Never prints, obviously.
}
print(paste("i =", i))
}
#> [1] "j = 1"
#> [1] "i = 1"
#> [1] "j = 1"
#> [1] "i = 2"
I am trying to make an R scripts generator. The problem is that the new files are presented as text files and not as R scripts. Is there any way to present them as R scripts?
Expected icon:
Result icon:
require("here", character.only = TRUE)
files.to.create <- c("main.R",
"functions.R",
"explore.R",
"initialize.R",
"load_data.R",
"build.R",
"analyze.R",
"build_ppt.R",
"prepare_markdown.R",
"markdown_report.Rmd")
try.to.make.files <- function(file.name, path){
if( .Platform$OS.type == "unix" ) {
new.file.name <- paste(path,"/", file.name, sep = "")
}
else {
new.file.name <- paste(path,"\\", file.name, sep = "")
}
cat(new.file.name,"\n")
unlink(new.file.name)
success <- file.create(new.file.name)
print(success)
return (TRUE)
}
invisible( lapply( files.to.create,
try.to.make.files,
here("src")))
UPDATE
Well it seems that if the file is empty Ubuntu handles it as empty text file, forcing it to show the txt icon and not the R icon. Filling the file solves the problem.
RStudio provides a nice function View (with uppercase V) to take a look into the data, but with R it's still nasty to get orientation in a large data set. The most common options are...
names(df)
str(df)
If you're coming from SPSS, R seems like a downgrade in this respect. I wondered whether there is a more user-friendly option? I did not find a ready-one, so I'd like to share my solution with you.
Using RStudio's built-in function View, it's white simple to have a variable listing for a data.frame similar to the one in SPSS. This function creates a new data.frame with the variable information and displays in the RStudio GUI via View.
# Better variables view
Varlist = function(sia) {
# Init varlist output
varlist = data.frame(row.names = names(sia))
varlist[["comment"]] = NA
varlist[["type"]] = NA
varlist[["values"]] = NA
varlist[["NAs"]] = NA
# Fill with meta information
for (var in names(sia)) {
if (!is.null(comment(sia[[var]]))) {
varlist[[var, "comment"]] = comment(sia[[var]])
}
varlist[[var, "NAs"]] = sum(is.na(sia[[var]]))
if (is.factor(sia[[var]])) {
varlist[[var, "type"]] = "factor"
varlist[[var, "values"]] = paste(levels(sia[[var]]), collapse=", ")
} else if (is.character(sia[[var]])) {
varlist[[var, "type"]] = "character"
} else if (is.logical(sia[[var]])) {
varlist[[var, "type"]] = "logical"
n = sum(!is.na(sia[[var]]))
if (n > 0) {
varlist[[var, "values"]] = paste(round(sum(sia[[var]], na.rm=T) / n * 100), "% TRUE", sep="")
}
} else if (is.numeric(sia[[var]])) {
varlist[[var, "type"]] = typeof(sia[[var]])
n = sum(!is.na(sia[[var]]))
if (n > 0) {
varlist[[var, "values"]] = paste(min(sia[[var]], na.rm=T), "...", max(sia[[var]], na.rm=T))
}
} else {
varlist[[var, "type"]] = typeof(sia[[var]])
}
}
View(varlist)
}
My recommendation is to store that as a file (e.g., Varlist.R) and whever you need it, just type:
source("Varlist.R")
Varlist(df)
Again please take note of the uppercase V using as function name.
Limitation: When working with data.frame, the listing will not be updated unless Varlist(df) is run again.
Note: R has a built-in option to view data with print. If working with pure R, just replace the View(varlist) by print(varlist). Yet, depending on screen size, Hmisc::describe() could be a better option for the console.
I am trying to use a function to modify another function default settings through formals but my problem is that when I check my function defaults afterwards then nothing has changed. My code (minus unrelated stuff) is:
ScouringSettings <- function(min.MAF=NULL, eq.thresh=NULL){
if (is.null(min.MAF) && is.null(eq.thresh)){
maf <- paste0("Minimum MAF criterion is: ", formals(GeneScour)$min.maf)
eq <- paste0("ChiĀ² HW equilibrium threshold: ", formals(GeneScour)$min.eq)
cat(paste(maf, eq, sep="\n"))
} else if (is.null(eq.thresh)) {
formals(GeneScour) <- alist(gene=, min.maf = min.MAF, min.eq = formals(GeneScour)$min.eq)
} else if (is.null()){
formals(GeneScour) <- alist(gene=, min.maf = formals(GeneScour)$min.maf, min.eq = eq.thresh)
} else {
formals(GeneScour) <- alist(gene=, min.maf = min.maf, min.eq = eq.thresh)
}
}
I thought that maybe it was because of a problem of scope or something so I tried printing out the defaults while still being in my first function and it printed :
$gene
$min.maf
min.MAF
$min.eq
formals(GeneScour)$min.eq
And even when I forcefully type
formals(GeneScour) <- alist(gene=, min.maf = 2, min.eq = formals(GeneScour)$min.eq)
The modification is not carried over outside of the ScouringSettings.
I am a bit lost, how could I manage that ?