首页 > 解决方案 > R之间的功能未正确执行

问题描述

我正在尝试在 r 中使用 between 函数,但代码执行不正确。当我运行我的代码时,其中一个调用没有按照我的要求进行。我认为这可能是我的人为错误,但我无法找出错误在哪里。

library(dplyr)
df<-data.frame(Motiv=c(-0.27,   -0.34,  -0.48,  -0.546, -0.41,  -0.39,  -0.3,   -0.44,  -0.46,  -0.3725,    -0.16,  -0.194, -0.105, -0.1,   -0.0680000000000001,    0.0600000000000001, 0.0600000000000001, 0.04,   0.0299999999999998, -0.27,  -0.7,   -0.65,  -0.67,  -0.7,   -0.55,  -0.51,  -0.4,   -0.47,  -0.38,  -0.31,  -0.4,   -0.42,  -0.45,  -0.53,  -0.83,  -0.94,  -1.086, -1.07,  -1.03,  -1.05,  -1.13,  -1.33,  -1.37,  -1.14,  -0.96,  -0.87,  -0.77,  -0.64,  -0.57,  -0.3,   -0.27,  -0.12,  -0.11,  -0.19,  -0.2,   -0.22,  0.0499999999999998, 0.19,   0.27,   0.34,   0.43)

df<-df%>%dplyr::mutate(Bucket=if_else(between(Motiv,-.14999,.15),"A",
                              if_else(between(Motiv,-.40,-.150001) | between(Motiv,.1501,.4),'B',
                                      if_else(between(Motiv,-.64999990, -.40001) | between(Motiv, .40001, .65),"C",
                                              if_else(between(Motiv,-.8999,-.650001) | between(Motiv,.650001,.9),"D",
                                                      if_else(between(Motiv,-1.14999,-.90001) | between(Motiv,.90001,1.15),"E",
                                                              if_else(between(Motiv,-1.39999,-1.150001) | between(Motiv,1.150001,1.4),"F",
                                                                      if_else(between(Motiv,-1.64999,-1.40001) | between(Motiv,1.40001,1.65),"G",
                                                                              if_else(between(Motiv,-1.9,-1.650001) | between(Motiv,1.650001,1.9),"H",
                                                                                      if_else(Motiv< (-1.90)| Motiv>1.9,"I",'J'))))))))))

我的输出是:问题是 J 在哪里,当它的 -.65 它应该是 C

df<-data.frame(Motiv=c(-0.27,   -0.34,  -0.48,  -0.546, -0.41,  -0.39,  -0.3,   -0.44,  -0.46,  -0.3725,    -0.16,  -0.194, -0.105, -0.1,   -0.0680000000000001,    0.0600000000000001, 0.0600000000000001, 0.04,   0.0299999999999998, -0.27,  -0.7,   -0.65,  -0.67,  -0.7,   -0.55,  -0.51,  -0.4,   -0.47,  -0.38,  -0.31,  -0.4,   -0.42,  -0.45,  -0.53,  -0.83,  -0.94,  -1.086, -1.07,  -1.03,  -1.05,  -1.13,  -1.33,  -1.37,  -1.14,  -0.96,  -0.87,  -0.77,  -0.64,  -0.57,  -0.3,   -0.27,  -0.12,  -0.11,  -0.19,  -0.2,   -0.22,  0.0499999999999998, 0.19,   0.27,   0.34,   0.43),Bucket=c( B,  B,  C,  C,  C,  B,  B,  C,  C,  B,  B,  B,  A,  A,  A,  A,  A,  A,  A,  B,  D,  J,  D,  D,  C,  C,  B,  C,  B,  B,  B,  C,  C,  C,  D,  E,  E,  E,  E,  E,  E,  F,  F,  E,  E,  D,  D,  C,  C,  B,  B,  A,  A,  B,  B,  B,  A,  B,  B,  B,  C)

标签: rtime-series

解决方案


首先,我建议远离嵌套if_else函数。dplyr具有case_when很好地满足这种需求的功能。

其次,您的代码正在执行预期的操作,并且您正在概述的窗口未捕获 -.65。见下文:

library(dplyr)

#DF taken from question
df<-data.frame(Motiv = c(-0.27,   -0.34,  -0.48,  -0.546, -0.41,  -0.39,  -0.3,   -0.44,  -0.46, 
                     -0.3725,    -0.16,  -0.194, -0.105, -0.1,   -0.0680000000000001,    0.0600000000000001,
                     0.0600000000000001, 0.04,   0.0299999999999998, -0.27,  -0.7,   -0.65,  -0.67,  -0.7,  
                     -0.55,  -0.51,  -0.4,   -0.47,  -0.38,  -0.31,  -0.4,   -0.42,  -0.45,  -0.53,  -0.83, 
                     -0.94,  -1.086, -1.07,  -1.03,  -1.05,  -1.13,  -1.33,  -1.37,  -1.14,  -0.96,  -0.87, 
                     -0.77,  -0.64,  -0.57,  -0.3,   -0.27,  -0.12,  -0.11,  -0.19,  -0.2,   -0.22,  0.0499999999999998, 
                     0.19,   0.27,   0.34,   0.43))

#OP code done with case_when - will reproduce the error
df$check <- case_when(between(df$Motiv,-.14999,.15) ~ "A" ,
                  between(df$Motiv,-.40,-.150001) | between(df$Motiv,.1501,.4) ~ 'B',
                  between(df$Motiv,-.64999990, -.40001) | between(df$Motiv, .40001, .65) ~ "C",
                  between(df$Motiv,-.8999,-.650001) | between(df$Motiv,.650001,.9) ~ "D",
                  #add the rest
                  TRUE ~ 'J')
#output (which is J)
df[df$Motiv == -.65,]

如果要捕获 -.65,请更改 C 的值:

#updated to produced expected answer
df$check <- case_when(between(df$Motiv,-.14999,.15) ~ "A" ,
                between(df$Motiv,-.40,-.150001) | between(df$Motiv,.1501,.4) ~ 'B',
                between(df$Motiv,-.65, -.40001) | between(df$Motiv, .40001, .65) ~"C", #need to capture -.65
                  between(df$Motiv,-.8999,-.650001) | between(df$Motiv,.650001,.9) ~ "D",
                  #add the rest
                  TRUE ~ 'J')
 #output (which is C)
 df[df$Motiv == -.65,]

推荐阅读