Problems with scan() function in R - r

I am trying to do a simple process to get values from console with scan()
function in R.
The above R code works well:
funent <- function(){
val <- scan(,,1)
return(as.character(val))
}
print("Seleccione: 1. consulta, 2.cirugia")
tipo <- funent()
But when I add more code below it doesn't work. The execution doesn't stop in scan.
funent <- function(){
val <- scan(,,1)
return(as.character(val))
}
print("Seleccione: 1. consulta, 2.cirugia")
tipo <- funent()
while((tipo < 1 | tipo >2 )){
if (tipo < 1 | tipo >2 ) {
print("Introduzca 1(consulta) o 2(cirugia)")
tipo <- funent()
}
}
Is there anything wrong in my R code?

Nothing is wrong with your code. The execution doesn't stop in scan because the value of tipo is 1 or 2. It works as expected when tipo is outside that range:
tipo = 0
while((tipo < 1 | tipo >2 )){
if (tipo < 1 | tipo >2 ) {
print("Introduzca 1(consulta) o 2(cirugia)")
tipo <- funent()
}
}
[1] "Introduzca 1(consulta) o 2(cirugia)"
1:

Related

How to add output of our loop into new column in our dataset in R?

I want to add the output of the loop in a new column "Compared_data".
Data set is libraries_four.
for (i in 1:20)
{
if ((Libraries_four[i,"PhyloAlps_iden"] == 1) & (Libraries_four[i,"ArctBorBryo_iden"] == 1 |
Libraries_four[i,"EMBL_143_iden"] == 1 | Libraries_four[i,"PhyloNorway_iden"] == 1 ))
{
print(TRUE)
}
else
{
print(FALSE)
}
}
The code is working fine but I tried the mutate function for the new column but it is not working. Is there any other way to add a new variable/column?
R is vectorised language, you would rarely need an explicit for loop. Try this :
library(dplyr)
Libraries_four <- Libraries_four %>%
mutate(result = PhyloAlps_iden == 1 & ArctBorBryo_iden == 1|
EMBL_143_iden == 1 | PhyloNorway_iden == 1)
This would create a new column called result in Libraries_four dataset.
You can also do this in base R :
Libraries_four <- transform(Libraries_four, result = PhyloAlps_iden == 1 & ArctBorBryo_iden == 1 | EMBL_143_iden == 1 | PhyloNorway_iden == 1)

What does the “slot doesn't exist” error message mean?

I'm trying to write an object and access to his parameters. I've got two files, menus.R, where I define the object, and main.R, where I use the object and try to access to a slot (parameter).
The code of both files are next:
menus.R
menu <- setClass("menu", slots=list(competition="numeric", stats="numeric"))
setMethod("show", "menu", function(object){
while (TRUE){
#Clean console
cat("\014")
cat("COMPARATIVA ENTRE EQUIPOS DE LA MISMA COMPETICION\n")
cat("-------------------------------------------------\n\n")
cat("1. Comparativa entre clubes de Liga DIA\n")
cat("2. Comparativa entre clubes de Liga Femenina 2 - Grupo 'A'\n")
cat("3. Comparativa entre clubes de Liga Femenina 2 - Grupo 'B'\n")
cat("0. Salir\n\n")
option <- readline("Selecciona opción: ")
option <- suppressWarnings(as.numeric(option))
if (!is.na(option)){
if (option == 1){
object#competition <- 14
}
if (option == 2){
object#competition <- 22
}
if (option == 3){
object#competition <- 23
}
readline("Espera ...")
if (option == 0)
break
}else{
readline("No es un número. Pulsa una tecla para introducir otra opción.")
}
}
})
main.R
menu(competition=0, stats=0)
print(menu#competition)
getClass(class(menu))
When I call menu(competition=0, stats=0) I can see what the method show gives me to me. This is correct. In show method I assign a value to competition. When I exit from show method the next instruction is print(menu#competition) and here is where I've got this error:
Error in print(menu#competition) : there is no a slot with name
"competition" for this object class "classGeneratorFunction"
Then with getClass(class(menu)) I've got this:
What am I doing wrong? How can I get access to competition or stats?
You are confusing the object constructor with the object itself.
menu(competition = 0, stats=0) generates you a new object of class menu, but you fail to save it somewhere, so it prints on the screen. Therefore your first, correct output.
But then, you want to manipulate the object. But you didn't save it! Instead, you try to manipulate the "object factory", menu(). The Type of the "object factory" is classGeneratorFunction, that's what you see.
This should work:
myMenuObject <- menu(competition=0, stats=0)
print(myMenuObject)
print(myMenuObject#competition)
getClass(class(myMenuObject))

if else multiple conditions comparing rows

I am strugling with this loop. I want to get "6" in the second row of column "Newcolumn".I get the following error.
Error in if (mydata$type_name[i] == "a" && mydata$type_name[i - :
missing value where TRUE/FALSE needed.
The code that I created:
id type_name name score newcolumn
1 a Car 2 2
1 a van 2 6
1 b Car 2 2
1 b Car 2 2
mydata$newcolumn <-c(0)
for (i in 1:length(mydata$id)){
if ((mydata$type_name [i] == "a") && (mydata$type_name[i-1] == "a") && ((mydata$name[i]) != (mydata$name[i-1]))){
mydata$newcolumn[i]=mydata$score[i]*3 }
else {
mydata$newcolumn[i]=mydata$score[i]*1
}
}
Thank you very much in advance
List starts at index 1 in R but like you are doing a i-1 in your loop starting at 1, your list is out of range (i-1=0) so your code can not return a True or False.

Function to find the start and end of conditional selection

I have a data that looks as follows:
Date | Time | Temperature
16995 | "12:00" | 23
16995 | "12:30" | 24
...
17499 | "23:30" | 23
17500 | "00:00" | 24
I'm writing a function to select a range of cases based on certain start and end time points. To do this I need to determine the start_pt and end_pt indices which should match with a pair of rows in the dataframe.
select_case <- function(df,date,time) {
start_pt = 0
end_pt = 0
for (i in 1:nrow(df)) {
if ((date[i] == 17000) & (time[i] == "12:00")) {
start_pt <- i
return(start_pt)
} else {
next
}
}
for (i in start_pt:nrow(df)) {
if (date[i] == 17500) {
end_pt <- i - 1
return(end_pt)
break
} else {
next
}
}
return(df[start_pt:end_pt,])
}
When I called:
test <- select_case(data,data$Date,data$Time)
test
I expect the following:
Date | Time | Temperature
17000 | "12:00" | 23
17000 | "12:30" | 24
...
17499 | "23:00" | 23
17499 | "23:30" | 23
Instead i got
[1] 1
Not sure where i got it wrong here. When I separately ran each of the two for-loops from R console and substituting in the corresponding arguments for each loop, i got the correct indices for both start_pt and end_pt.
I tried putting each loop in a separate function, named sta(date,time) and end(date). Then I bind them in the following function:
binder <- function(date,time) {
return(sta(date,time),end(date))
}
and call
sta_end <- binder(date,time)
I got the error:
Error in return(sta(date, time), end(date)) :
multi-argument returns are not permitted
So i combined them and it worked:
binder <- function(date,time) {
return(c(sta(date,time),end(date)))
}
sta_end <- binder(date,time)
[1] 1 <an index for end_pt>
So the mistake i made in my original function is that i use return() 3 times and the function will only return the first one which is start_pt. So I took out the first two return() and retained the last one:
return(df[start_pt:end_pt,])
This worked, i got the expected result.

Aggregate as new column in R

Input:
Time,id1,id2
22:30,1,0
22:32,2,1
22:33,1,0
22:34,2,1
Output Desired
Time,Time2,id1,id2
22:30,22:33,1,0
22:32,22:34,2,1
Output by my code
Time,id1,id2
22:30,22:33,1,0
22:32,22:34,2,1
What change should I make to my code aggregate(Time~,df,FUN=toString)
My id1 and id2 together is the key and times are in and out time for each key. I need to get time in and time out as separate column values. Currently they are in column Time.
I tried it using awk also.
If you do not want to use any packages, this will work:
df <- aggregate(Time~.,df,FUN=toString)
df
#output
id1 id2 Time
1 0 22:30, 22:33
2 1 22:32, 22:34
df$Time2 <- lapply(strsplit(as.character(df$Time), ","),"[", 2)
df$Time <- lapply(strsplit(as.character(df$Time), ","),"[", 1)
df
#output
id1 id2 Time Time2
1 0 22:30 22:33
2 1 22:32 22:34
With awk
$ cat time.awk
BEGIN {
FS = OFS = ","
}
function in_time() {
n++
store[id1, id2] = n
itime[n] = time; iid1[n] = id1; iid2[n] = id2
}
function out_time( i) {
i = store[id1, id2]
otime[i] = time
}
NR > 1 {
time = $1; id1 = $2; id2 = $3
if ((id1, id2) in store) out_time()
else in_time()
}
END {
print "Time,id1,id2"
for (i = 1; i <= n; i++)
print itime[i], otime[i], iid1[i], iid2[i]
}
Usage:
awk -f time.awk file.dat

Resources