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
Getting error the condition has length 1 and only the first element will be used when using if else loop
if
and else
should be used on logical conditions that are length 1. You are asking if a vector (OldTimeColumn
) of some length n
is equal to a vector of a single value TRUE
-- so that's why the warning message says what it says, and it only evaluates the first element of OldTimeColumn
by comparing it to TRUE
.
A better way for your particular example might be to use the case_when
structure.
library(dplyr)
library(stringr)
df <- data.frame(
OldTimeColumn = c("12", "1", "2", "3", "4"),
stringsAsFactors = F
)
df <- df %>%
mutate(NewTimeColumn = case_when(
str_detect(OldTimeColumn, "^12") ~ "12",
str_detect(OldTimeColumn, "^1") ~ "1",
str_detect(OldTimeColumn, "^2") ~ "2",
str_detect(OldTimeColumn, "^3") ~ "3",
TRUE ~ "11"
))
df
OldTimeColumn NewTimeColumn
1 12 12
2 1 1
3 2 2
4 3 3
5 4 11
Trying to do this with ifelse
(which does work on evaluating vectors) would be more cumbersome but can be done:
df <- df %>%
mutate(NewTimeColumn = ifelse(str_detect(OldTimeColumn, "^12") == TRUE,
"12", ifelse(str_detect(OldTimeColumn, "^1") == TRUE,
"1", ifelse(str_detect(OldTimeColumn, "^2") == TRUE,
"2", ifelse(str_detect(OldTimeColumn, "^3") == TRUE, "3", "11")))))
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 = " ")
)
}
“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
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))
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"
What does warning mean: the condition has length 1 and only the first element will be used
This,
paste(df.short$AD, df.short$ED, sep="")
is a vector, not of length 1, so when you pass that to your function, you are testing a vector against a scalar:
nchar(x) == 5
I suggest looping over your function using an apply function, something like
mapply(fixED, x = paste(df.short$AD, df.short$ED, sep=""))
Error in the if function: the condition has length 1 and only the first element will be used
You got that error because you can only evaluate a single T/F in if (...)
. However, data[1, ] < ...
is a vectorised evaluation that returns a T/F vector of a length n (i.e. 1000 for your case above). Nevertheless, I think your second function (est_L
) does not match the equation shown in that image. Consider the following implementation instead:
L <- function(n) {
del <- 0.9 * sqrt(2 * log(n))
data <- rnorm(n)
mean(exp(del * data - 0.5 * del * del))
}
L_tilde <- function(n) {
del <- 0.9 * sqrt(2 * log(n))
data <- rnorm(n)
mean(exp(del * data * ifelse(data < sqrt(2 * log(n)), 1, 0) - 0.5 * del * del))
}
Then you can just
hist(replicate(1000, L_tilde(1000)))
Output
Related Topics
Directly Creating Dummy Variable Set in a Sparse Matrix in R
Predict.Lm() with an Unknown Factor Level in Test Data
Setting Function Defaults R on a Project Specific Basis
How to Force Specific Order of the Variables on the X Axis
Splitting a Data.Frame by a Variable
Creating a Local R Package Repository
How to Separate Two Plots in R
How to Show a Legend on Dual Y-Axis Ggplot
R - How to Get Row & Column Subscripts of Matched Elements from a Distance Matrix
Merge Data Frames Based on Rownames in R
How to Override a Non-Visible Function in the Package Namespace
Re-Ordering Bars in R's Barplot()