0

Function group_tenure is working but not able to write “0-1 Days” etc in new column along with the filtered value. Here TodayNew is the column in excel which has aging.

group_tenure  <- function(TodayNew){
  if (TodayNew >= 0 & TodayNew <= 1){
     return ('0-1 Days')
  }else if(TodayNew > 1 & TodayNew <= 4){
    return('2-4 Days')
  }else if (TodayNew > 4 & TodayNew <= 7){
     return('5-7 Days')
  }else if (TodayNew > 7 & TodayNew <=15){
     return('8-15 Days')
  }else if (TodayNew > 15 & TodayNew <=30){
     return('16-30 Days')
  }else if (TodayNew > 30){
    return('More than 30 Days')
  }
}

Showing values of group_tenure as below but not able to write in new column.

group_tenure(1)
[1] "0-1 Days"
> group_tenure(2)
[1] "2-4 Days"
> group_tenure(5)
[1] "5-7 Days"
> group_tenure(8)
[1] "8-15 Days"
> group_tenure(16)
[1] "16-30 Days"
> group_tenure(31)
[1] "More than 30 Days"
r2evans
  • 141,215
  • 6
  • 77
  • 149
Shweta
  • 23
  • 7

1 Answers1

1

Your function is not vectorized, so if I'm interpreting you correctly, it will not be something you can call on a vector (i.e., data frame column).

x <- c(1, 2, 5, 8, 16, 31)
group_tenure(x)
# Warning in if (TodayNew >= 0 & TodayNew <= 1) { :
#   the condition has length > 1 and only the first element will be used
# [1] "0-1 Days"

If you need that, then either use

Vectorize(group_tenure)(x)
# [1] "0-1 Days"          "2-4 Days"          "5-7 Days"          "8-15 Days"        
# [5] "16-30 Days"        "More than 30 Days"

or vectorize your function. One way to do that efficiently here is to use cut:

group_tenure2 <- function(TodayNew) {
  as.character(
    cut(TodayNew, c(0, 1, 4, 7, 15, 30, Inf),
        labels = c("0-1 Days", "2-4 Days", "5-7 Days", "8-15 Days", "16-30 Days", "More than 30 Days"),
        include.lowest = TRUE)
  )
}
group_tenure2(x)
# [1] "0-1 Days"          "2-4 Days"          "5-7 Days"          "8-15 Days"        
# [5] "16-30 Days"        "More than 30 Days"
r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Thanks its working. But now I am trying to write these group_tenure2(x) values ie "0-1 Days" etc in a new column in accordance with the TodayNew column data. – Shweta Dec 18 '20 at 07:06
  • e.g filter TodayNew for "0 to1" and write "0-1 Days" in new column called Aging. so tried below : age <- group_tenure2(x) #Adding new column to excel called "Age" df["Age"] <- group_tenure2(x) Throwing below error : Error: Assigned data `group_tenure2(x)` must be compatible with existing data. x Existing data has 1344 rows. x Assigned data has 6 rows. i Only vectors of size 1 are recycled. – Shweta Dec 18 '20 at 07:19
  • Yeah, can't help if I don't know what I'm working with (and your question does not include any relevant data). Please provide a small, representative sample of your data in your question, by using either `data.frame(...)` or the output from `dput(head(x))`. – r2evans Dec 18 '20 at 13:26
  • #Filtering data as per aging and writing values in newly added column accordingly zerotoone <- filter(df, df$TodayNew %in% c(0,1)) df["AgingNew"] <- "0-1 Days" twotofour <- filter(df, df$TodayNew %in% c(2,3,4)) df["AgingNew"] <- "2-4 Days" fivetoseven <- filter(df, df$TodayNew %in% c(5,6,7)) df["AgingNew"] <- "5-7 Days" eighttofifteen <- filter(df, df$TodayNew %in% c(8,9,10,11,12,13,14,15)) df["AgingNew"] <- "8-15 Days" – Shweta Dec 21 '20 at 09:57
  • Above is the small example of whatever i am trying to get. Basically wanted to filter values as per aging and write data accordingly in newly added column. @r2evans – Shweta Dec 21 '20 at 09:59
  • Shweta, ***please***: given what I know, it works. Given what you've provided, it works. Since it appears that your data does not represent my inference, it will help you significantly if you provide sample data and make this a reproducible problem. Please read one or more of the following links for good ways to do that: https://stackoverflow.com/q/5963269, [mcve], and https://stackoverflow.com/tags/r/info. – r2evans Dec 21 '20 at 13:48