R递归条件嵌套有两个条件

时间:2018-02-01 09:45:08

标签: r nested conditional

我已经看到了一些相似的问题,但尚未解决这个问题。希望不要错。

我有这样的DF:

Invoices<-c(20171100247, 20171100408, 20171200376,20171201052, 21609000088)
Oustanding.days<-c(15,85,96,251,123)
Quantile.low<-c(25,21,22,23,24)
Quantile.Medium<-c(45,65,85,93,74)
Quantile.top<-c(74,89,101,175,125)
Remittances<-c(25,47,5,7,2)
df<-cbind(Invoices,Oustanding.days,Quantile.low,Quantile.Medium,Quantile.top,Remittances)
df
        Invoices Oustanding.days Quantile.low Quantile.Medium Quantile.top Remittances
[1,] 20171100247              15           25              45           74          25
[2,] 20171100408              85           21              65           89          47
[3,] 20171200376              96           22              85          101           5
[4,] 20171201052             251           23              93          175           7
[5,] 21609000088             123           24              74          125           2

我想在条件中创建一个 “付款准确度” 列:

如果汇款低于5,那么我想按行分配准确度:

1)df $ Outstanding.days&lt; 60 - &gt;打印“太早”

2)df $ Outstanding.days&gt; 60&lt; 90 - &gt;打印“早期”

3)df $ Outstanding.days&gt; 90 - &gt;打印“迟到”

如果汇款超过5,我想为其分配分位数:

1)df $ Outstanding.days&lt; Quantile.low - &gt;打印“太早”

2)df $ Outstanding.days&gt;分位数。低&LT;分位数。介质 - &gt;打印“早期”

3)df $ Outstanding.days&gt;分位数.Medium&amp; &LT;分位数 - 顶部 - &gt;打印“日期”

4)df $ Outstanding.days&gt;分位数 - 顶部 - &gt;打印“迟到”

我正在尝试使用transform和嵌套条件

df.final<-transform(df,Payment.accuracy=( 
if (df$OutStandingDays <= df$Quantile.low) {print 
("too early")}
else (print ("NA"))))

但我做错了。

谢谢。

4 个答案:

答案 0 :(得分:3)

在此解决方案中,我考虑remittances上的两个条件分割数据,然后按行折叠。

library(tidyverse)

# First condition
df_less5 = df %>% filter(Remittances < 5)

df_less5 = df_less5 %>% 
  mutate(payment_accuracy = ifelse(Oustanding.days < 60, "too early",
                                   ifelse(Oustanding.days >60 & Oustanding.days <90, "early", "late")))

# Second condition
df_more5 = df %>% filter(Remittances > 5)

df_more5 = df_more5 %>% 
  mutate(payment_accuracy = ifelse(Oustanding.days < Quantile.low, "too early",
                                   ifelse(Oustanding.days > Quantile.low & Oustanding.days < Quantile.Medium, "early",
                                          ifelse(Oustanding.days > Quantile.Medium & Oustanding.days < Quantile.top, "on_date", 
                                                 ifelse(Oustanding.days > Quantile.top, "late", "other")))))


# new dataset
df_new = bind_rows(df_less5, df_more5)                                  

这给出了这个输出:

 > df_new

  Invoices Oustanding.days Quantile.low Quantile.Medium Quantile.top Remittances payment_accuracy
1 21609000088             123           24              74          125           2             late
2 20171100247              15           25              45           74          25        too early
3 20171100408              85           21              65           89          47          on_date
4 20171201052             251           23              93          175           7             late

答案 1 :(得分:2)

我添加了一个更正为df的列(如果你想提取该列,之后会很容易),我用了你最后的代码行:

 Invoices<-c(20171100247, 20171100408, 20171200376,20171201052, 21609000088)
 Oustanding_days<-c(15,85,96,251,123)
 Quantile_low<-c(25,21,22,23,24)
 Quantile_Medium<-c(45,65,85,93,74)
 Quantile_top<-c(74,89,101,175,125)
 Remittances<-c(25,47,5,7,2)
 df<-  cbind(Invoices,Oustanding_days,Quantile_low,Quantile_Medium,Quantile_top,Remittances)
 df <- as.data.frame(df)



 for (i in 1:length(df[,1])){
   if(df$Oustanding_days[i] <= df$Quantile_low[i]){
     df$final[i] <- print("too early")
   } else {
     df$final[i] <-print("NA")
   }
 }

通过该示例,您应该能够重现所需的所有条件。

祝你好运!

答案 2 :(得分:2)

我们可以使用包中的TRUE ~ NA_character_根据多个条件分配值。嵌套的ifelse语句或for循环有时可能过于复杂且难以阅读。

最后一行NA是为不符合上述任何条件的行指定library(dplyr) df2 <- df %>% mutate(`Payment accuracy` = case_when( Remittances < 5 & Outstanding.days < 60 ~ "too early", Remittances < 5 & Outstanding.days >= 60 & Outstanding.days < 90 ~ "early", Remittances < 5 & Outstanding.days >= 90 ~ "late", Remittances >= 5 & Outstanding.days < Quantile.low ~ "too early", Remittances >= 5 & Outstanding.days >= Quantile.low & Outstanding.days < Quantile.Medium ~ "early", Remittances >= 5 & Outstanding.days >= Quantile.Medium & Outstanding.days < Quantile.top ~ "On date", Remittances >= 5 & Outstanding.days >= Quantile.top ~ "late", TRUE ~ NA_character_ )) df2 # Invoices Outstanding.days Quantile.low Quantile.Medium Quantile.top Remittances Payment accuracy # 1 20171100247 15 25 45 74 25 too early # 2 20171100408 85 21 65 89 47 On date # 3 20171200376 96 22 85 101 5 On date # 4 20171201052 251 23 93 175 7 late # 5 21609000088 123 24 74 125 2 late

Outstanding.days

数据

请注意您的原始代码中存在拼写错误,例如Remittancescbind。此外,您没有按data.frame创建数据框。您需要的功能是stringsAsFactors = FALSEInvoices<-c(20171100247, 20171100408, 20171200376,20171201052, 21609000088) Outstanding.days<-c(15,85,96,251,123) Quantile.low<-c(25,21,22,23,24) Quantile.Medium<-c(45,65,85,93,74) Quantile.top<-c(74,89,101,175,125) Remittances<-c(25,47,5,7,2) df <- data.frame(Invoices, Outstanding.days, Quantile.low, Quantile.Medium, Quantile.top, Remittances, stringsAsFactors = FALSE) 是为了确保列类型是字符,而不是因素。

{{1}}

答案 3 :(得分:1)

您可以使用dplyr和嵌套ifelse - 语句。

请注意,>Quantile.low & < Quantile.Medium之类的语句排除了它等于其中一个值的情况,您应该使用<=。即它应该是>=Quantile.low & < Quantile.Medium>Quantile.low & <= Quantile.Medium。在下面的例子中,我假设了后一种选择。

df <- as.data.frame(df)   
library(dplyr)

df %>% mutate(x=ifelse(Remittances<5,
                     ifelse(Oustanding.days<=60,'too early',
                            ifelse(Oustanding.days>60 & Oustanding.days<=90,'early','late')),NA)) %>%
  mutate(x=ifelse(Remittances>=5,
                  ifelse(Oustanding.days<=Quantile.low,'too early',
                         ifelse(Oustanding.days>Quantile.low & Oustanding.days<=Quantile.Medium,'low',
                                ifelse(Oustanding.days>Quantile.Medium & Oustanding.days <= Quantile.top,'On date','late'))),x))

返回:

     Invoices Oustanding.days Quantile.low Quantile.Medium Quantile.top Remittances         x
1 20171100247              15           25              45           74          25 too early
2 20171100408              85           21              65           89          47   On date
3 20171200376              96           22              85          101           5   On date
4 20171201052             251           23              93          175           7      late
5 21609000088             123           24              74          125           2      late

希望这有帮助!