“条件的长度 > 1,并且只有第一个元素将被使用”来自数据框上嵌套的“if elses”的警告
“the condition has length > 1 and only the first element will be used” warning from nested `if elses' over a dataframe
我有一个包含两列的数据框,Q10_headache_tibble:
structure(list(df_questionaire.headaches = c(0L, 2L, 2L, 2L,
0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 2L, 2L, 2L,
2L, 0L, 2L, 0L, 2L, 0L, 2L, NA, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L,
0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 0L, 0L, 0L,
0L, 2L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L,
0L, 0L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 2L, 0L, 0L, 2L, 2L, 2L,
0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 2L,
2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 2L,
0L, 2L, 2L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 2L, 2L, 2L, 0L, 0L,
0L, 0L, 2L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 0L, 0L, 2L,
2L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 2L, 0L, 0L,
0L, 0L, 2L, 2L, 2L, 2L, 2L, 0L, 2L, 0L, 0L), df_questionaire.headaches_covid = c(0L,
0L, 2L, 2L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 2L,
2L, 2L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L, NA, 2L, 2L, 0L, 0L, 0L,
2L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 0L,
0L, 2L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L,
0L, 0L, 774L, 0L, 0L, 0L, 2L, 2L, 774L, 0L, 0L, 0L, 2L, 0L, 2L,
0L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 0L,
0L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 0L, 2L,
2L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 2L, 0L, 2L, 0L, 0L, 0L, 2L,
2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L,
2L, 0L, 0L, 2L, 2L, 0L, 774L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 0L,
2L, 0L, 2L, 774L, 0L, 2L, 0L, 0L, 2L, 2L, 2L, 2L, 774L, 0L, 0L,
774L)), row.names = c(NA, -175L), class = c("tbl_df", "tbl",
"data.frame"))
我创建了一个函数,它应该 return 一个字符向量 (Q10_incidence) 与 nrow(df_headache_tibble) 的长度相同,基于应用于数据框的嵌套条件,按行。 Q10_incidence[i] 应该是将函数应用于 df_headache_tibble[i,1] 和 df_headache_tibble[i,2] 的结果,我打算为此使用 mapply。
incidence_headaches<-function(x,y){
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'
}
}
}
Q10_incidence<-mapply(incidence_headaches, Q10_headache_tibble[,1], Q10_headache_tibble[,2])
当我打电话时
mapply(incidence_headaches, Q10_headache_tibble[,1], Q10_headache_tibble[,2])
我在几个警告中收到可怕的“条件的长度 > 1,并且只会使用第一个元素”。我怎么能处理这个?
虽然我发现了几个关于同一个“condition has length (...)”警告的问题,但我仍然觉得这个话题很混乱。欢迎“傻瓜式”演练。
好像和向量化有关系,把函数换成嵌套的ifelse()结构就可以解决,会很乱
我可能需要在很多场合使用类似的功能,不确定什么是最好的解决方法。
1) 就我个人而言,我尽可能多地使用 R,只使用其众多命令中的一小部分。也许一个简单的 apply
是一种更简单的管理方法。 apply
和 MARGIN = 1
会将 data.frame 的每一行赋予一个函数。所以我对你的函数做了这个小改动(这里只对前 3 行感兴趣,其余的是复制和粘贴):
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'
}
}
}
然后您可以像这样使用简单的 apply
:
apply(df_headache_tibble, MARGIN = 1, incidence_headaches)
要得到这样的东西:
> 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
显然是一个完美的函数,没有理由不使用它。你的问题是:tibbles 是 data.frames 但它们的行为不像 data.frames。这很好用:
mapply(incidence_headaches,
as.data.frame(df_headache_tibble)[,1],
as.data.frame(df_headache_tibble)[,2])
当您仅从 data.frame 中提取一行时,它将为您提供一个向量,当您仅从小标题中提取一行时,它将为您提供一个小标题。 Hadley 与发明 R data.frame 的人对事情应该如何运作有不同的看法。
中有一些解决方法
mapply(incidence_headaches,
df_headache_tibble[,1, drop = TRUE],
df_headache_tibble[,2, drop = TRUE])
在此处阅读详细信息,但最重要的是要始终注意,虽然小标题是 data.frames,但它们的行为并不完全像 data.frames:https://tibble.tidyverse.org/reference/subsetting.html
这是一个完全矢量化的解决方案,不需要 *apply
循环。
incidence_headaches <- function(x, y){
# create the return vector
output <- rep('no_headache', NROW(x))
# conditions for 'x'
x_2 <- x == 2
x_vec <- x %in% c(0, 774, 775, 776)
# conditions for 'y'
y_2 <- y == 2
y_vec <- y %in% c(0, 774, 775, 776)
# assign the return values given a combination
# of the conditions above. Note that the
# condition y == 0 is only used once and
# therefore a logical vector is not needed
output[is.na(x) | is.na(y)] <- NA_character_
output[x_2 & y_2] <- 'previous_headache_maintained'
output[x_2 & y == 0] <- 'previous_headache_ceased'
output[x_vec & y_2] <- 'new_onset_headache'
output[x_vec & y_vec] <- 'no_headache'
# return to caller
output
}
Q10_incidence <- incidence_headaches(Q10_headache_tibble[, 1], Q10_headache_tibble[, 2])
head(Q10_incidence)
#[1] "no_headache" "previous_headache_ceased"
#[3] "previous_headache_maintained" "previous_headache_maintained"
#[5] "no_headache" "no_headache"
我有一个包含两列的数据框,Q10_headache_tibble:
structure(list(df_questionaire.headaches = c(0L, 2L, 2L, 2L,
0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 2L, 2L, 2L,
2L, 0L, 2L, 0L, 2L, 0L, 2L, NA, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L,
0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 0L, 0L, 0L,
0L, 2L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L,
0L, 0L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 2L, 0L, 0L, 2L, 2L, 2L,
0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 2L,
2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 2L,
0L, 2L, 2L, 0L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 2L, 2L, 2L, 0L, 0L,
0L, 0L, 2L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 0L, 0L, 2L,
2L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 2L, 0L, 0L,
0L, 0L, 2L, 2L, 2L, 2L, 2L, 0L, 2L, 0L, 0L), df_questionaire.headaches_covid = c(0L,
0L, 2L, 2L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 2L,
2L, 2L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L, NA, 2L, 2L, 0L, 0L, 0L,
2L, 2L, 0L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 0L,
0L, 2L, 0L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 2L,
0L, 0L, 774L, 0L, 0L, 0L, 2L, 2L, 774L, 0L, 0L, 0L, 2L, 0L, 2L,
0L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 0L, 0L, 0L,
0L, 2L, 2L, 0L, 2L, 0L, 2L, 2L, 0L, 2L, 0L, 0L, 2L, 0L, 0L, 2L,
2L, 2L, 0L, 2L, 0L, 2L, 0L, 0L, 2L, 2L, 0L, 2L, 0L, 0L, 0L, 2L,
2L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 0L, 0L, 2L, 0L, 0L, 0L, 0L, 0L,
2L, 0L, 0L, 2L, 2L, 0L, 774L, 0L, 2L, 0L, 0L, 0L, 0L, 0L, 0L,
2L, 0L, 2L, 774L, 0L, 2L, 0L, 0L, 2L, 2L, 2L, 2L, 774L, 0L, 0L,
774L)), row.names = c(NA, -175L), class = c("tbl_df", "tbl",
"data.frame"))
我创建了一个函数,它应该 return 一个字符向量 (Q10_incidence) 与 nrow(df_headache_tibble) 的长度相同,基于应用于数据框的嵌套条件,按行。 Q10_incidence[i] 应该是将函数应用于 df_headache_tibble[i,1] 和 df_headache_tibble[i,2] 的结果,我打算为此使用 mapply。
incidence_headaches<-function(x,y){
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'
}
}
}
Q10_incidence<-mapply(incidence_headaches, Q10_headache_tibble[,1], Q10_headache_tibble[,2])
当我打电话时
mapply(incidence_headaches, Q10_headache_tibble[,1], Q10_headache_tibble[,2])
我在几个警告中收到可怕的“条件的长度 > 1,并且只会使用第一个元素”。我怎么能处理这个? 虽然我发现了几个关于同一个“condition has length (...)”警告的问题,但我仍然觉得这个话题很混乱。欢迎“傻瓜式”演练。
好像和向量化有关系,把函数换成嵌套的ifelse()结构就可以解决,会很乱
我可能需要在很多场合使用类似的功能,不确定什么是最好的解决方法。
1) 就我个人而言,我尽可能多地使用 R,只使用其众多命令中的一小部分。也许一个简单的 apply
是一种更简单的管理方法。 apply
和 MARGIN = 1
会将 data.frame 的每一行赋予一个函数。所以我对你的函数做了这个小改动(这里只对前 3 行感兴趣,其余的是复制和粘贴):
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'
}
}
}
然后您可以像这样使用简单的 apply
:
apply(df_headache_tibble, MARGIN = 1, incidence_headaches)
要得到这样的东西:
> 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
显然是一个完美的函数,没有理由不使用它。你的问题是:tibbles 是 data.frames 但它们的行为不像 data.frames。这很好用:
mapply(incidence_headaches,
as.data.frame(df_headache_tibble)[,1],
as.data.frame(df_headache_tibble)[,2])
当您仅从 data.frame 中提取一行时,它将为您提供一个向量,当您仅从小标题中提取一行时,它将为您提供一个小标题。 Hadley 与发明 R data.frame 的人对事情应该如何运作有不同的看法。
中有一些解决方法mapply(incidence_headaches,
df_headache_tibble[,1, drop = TRUE],
df_headache_tibble[,2, drop = TRUE])
在此处阅读详细信息,但最重要的是要始终注意,虽然小标题是 data.frames,但它们的行为并不完全像 data.frames:https://tibble.tidyverse.org/reference/subsetting.html
这是一个完全矢量化的解决方案,不需要 *apply
循环。
incidence_headaches <- function(x, y){
# create the return vector
output <- rep('no_headache', NROW(x))
# conditions for 'x'
x_2 <- x == 2
x_vec <- x %in% c(0, 774, 775, 776)
# conditions for 'y'
y_2 <- y == 2
y_vec <- y %in% c(0, 774, 775, 776)
# assign the return values given a combination
# of the conditions above. Note that the
# condition y == 0 is only used once and
# therefore a logical vector is not needed
output[is.na(x) | is.na(y)] <- NA_character_
output[x_2 & y_2] <- 'previous_headache_maintained'
output[x_2 & y == 0] <- 'previous_headache_ceased'
output[x_vec & y_2] <- 'new_onset_headache'
output[x_vec & y_vec] <- 'no_headache'
# return to caller
output
}
Q10_incidence <- incidence_headaches(Q10_headache_tibble[, 1], Q10_headache_tibble[, 2])
head(Q10_incidence)
#[1] "no_headache" "previous_headache_ceased"
#[3] "previous_headache_maintained" "previous_headache_maintained"
#[5] "no_headache" "no_headache"