我已经看到了一些相似的问题,但尚未解决这个问题。希望不要错。
我有这样的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"))))
但我做错了。
谢谢。
答案 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)
我们可以使用dplyr包中的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
数据强>
请注意您的原始代码中存在拼写错误,例如Remittances
和cbind
。此外,您没有按data.frame
创建数据框。您需要的功能是stringsAsFactors = FALSE
。 Invoices<-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
希望这有帮助!