Interpreting "Condition Has Length ≫ 1" Warning from 'If' Function

Interpreting condition has length 1 warning from `if` function

maybe you want ifelse:

a <- c(1,1,1,1,0,0,0,0,2,2)
ifelse(a>0,a/sum(a),1)

[1] 0.125 0.125 0.125 0.125 1.000 1.000 1.000 1.000
[9] 0.250 0.250

How to correct this warning “condition has length 1” warning from `if` function?

I would strongly suggest to not grow your data.frame like that but like this

file.names <- list.files(paste(in.path2,"CSV",sep =""))
input_list <- list()
for(f in file.names){
file <- paste(in.path2,"CSV/", f, sep = "")
input_list[[f]] <- read.csv(file, stringsAsFactors = F, na.strings = c("", " "))
print(f)
}
dat <- do.call(rbind, input_list)

This is much faster and you do not need to test if dat is.na or not

What does the error the condition has length 1 and only the first element will be used mean?

the problem is that you are using an if-statement with a vector. This is not allowed and doesn't work as you would expect. You can use the case_when function from dplyr.

library(dplyr)

split_firstname <- function(full_name){
x <- stringr::str_count(full_name, " ")
case_when(
x == 1 ~ stringr::word(full_name, 1),
x == 2 ~ paste(stringr::word(full_name,1), stringr::word(full_name,2), sep = " "),
x == 4 ~ paste(stringr::word(full_name,1), stringr::word(full_name,2), stringr::word(full_name,3), stringr::word(full_name,4), sep = " ")
)
}

Warning message: In if (data$body 0) { : the condition has length 1 and only the first element will be used

You want to try the following solution:

data$shadow.up <- ifelse(data$body > 0, data$High - data$Close, data$High - data$Open)
data$shadow.down <- ifelse(data$body > 0, data$Open - data$Low, data$Close - data$Low)

In your solution the if condition gets a vector of logicals and it will use only the first value in that vector.

If statement error - the condition has length 1 and only the first element will be used

You can try use ifelse the vectorized version of if

df$Year1 <- ifelse(df$pos1 == 3 ,  str_sub(df$Date,-4,-1) ,
str_sub(df$Date, 1, 4))

If-else error statement `the condition has length 1`in R?

We can use ifelse instead of if/else because if/else expects a vector of length 1 and is not vectorized for length greater than 1.

df$indexclass  <- with(df, ifelse(index >= 0.8, "P",
ifelse(index <= (-0.8), "A", "S")))
df$indexclass
#[1] "P" "S" "S" "S" "A" "A"

If there are multiple comparisons, an option would be either cut orfindInterval

c("A", "S","P")[with(df,  findInterval(index, c(-0.8, 0.8)))  + 1]
#[1] "P" "S" "S" "S" "A" "A"

The condition has length 1 and only the first element will be used

You get the error because if can only evaluate a logical vector of length 1.

Maybe you miss the difference between & (|) and && (||). The shorter version works element-wise and the longer version uses only the first element of each vector, e.g.:

c(TRUE, TRUE) & c(TRUE, FALSE)
# [1] TRUE FALSE

# c(TRUE, TRUE) && c(TRUE, FALSE)
[1] TRUE

You don't need the if statement at all:

mut1 <- trip$Ref.y=='G' & trip$Variant.y=='T'|trip$Ref.y=='C' & trip$Variant.y=='A'
trip[mut1, "mutType"] <- "G:C to T:A"

“the condition has length 1 and only the first element will be used” warning from nested `if elses' over a dataframe

1) Personally I try to do as much R as I can with only a small subset of its many commands. Maybe a simple apply is an easier way to manage this. apply with MARGIN = 1 will give each row pf your data.frame to a function. So I made this slight change to your function (just the first 3 lines are of interest here, the rest is copy&paste):

incidence_headaches<-function(row){
x <- row[1]
y <- row[2]
if (is.na(x)|is.na(y)){
output<-NA
}
else if (x==2){
if (y==2){
output<-'previous_headache_maintained'
}else if(y==0){
output<-'previous_headache_ceased'
}
}else if(x %in% c(0,774,775,776)){
if (y==2){
output<-'new_onset_headache'
}else if (y %in% c(0, 774, 775, 776)){
output<-'no_headache'
}
}
}

You can then use simple apply like this:

apply(df_headache_tibble, MARGIN = 1, incidence_headaches)

To get something like this:

> apply(df_headache_tibble, MARGIN = 1, incidence_headaches)
[1] "no_headache" "previous_headache_ceased" "previous_headache_maintained"
[4] "previous_headache_maintained" "new_onset_headache" "no_headache"
[7] "no_headache" "no_headache" "previous_headache_ceased"
[10] "new_onset_headache" "previous_headache_ceased" "previous_headache_maintained"
[13] "no_headache" "previous_headache_ceased" "no_headache"
...

2) mapply is obviously a perfectly working function and there is no reason not to use it. Your problem was: tibbles are data.frames but they do not behave like data.frames. This works well:

mapply(incidence_headaches, 
as.data.frame(df_headache_tibble)[,1],
as.data.frame(df_headache_tibble)[,2])

When you subset only one row from a data.frame, it will give you a vector, when you subset only one row from a tibble, it will give you a tibble. Hadley has a different opinion on how things should work then the people who invented the R data.frame. There are ways around this as in

mapply(incidence_headaches, 
df_headache_tibble[,1, drop = TRUE],
df_headache_tibble[,2, drop = TRUE])

Read details here but mostly be always aware, that although tibbles are data.frames they do not behave exactly like data.frames: https://tibble.tidyverse.org/reference/subsetting.html



Related Topics



Leave a reply



Submit