Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!
Hello! I am getting an error about ambiguous strings when I try to run the following R script in Power BI. I am trying to determind a status for a part per day based on the create date and complete date. It works great in Rstudio with no errors. Here's some sample data:
Id | OldId | PartId | ProcessStepId | CreateDate | CompleteDate | Order | DueDate | Check |
1525988 | 0 | 450475 | 3 | 2021-06-10T16:38:09.5970000 | null | 0 | 6/12/2021 | FALSE |
1525985 | 0 | 450474 | 3 | 2021-06-10T16:38:06.4100000 | null | 0 | 6/14/2021 | FALSE |
1525982 | 0 | 450473 | 3 | 2021-06-10T16:38:03.3500000 | null | 0 | 6/15/2021 | FALSE |
1525979 | 0 | 450472 | 3 | 2021-06-10T16:37:59.8000000 | null | 0 | 6/16/2021 | FALSE |
1525976 | 0 | 450471 | 3 | 2021-06-10T16:37:56.7130000 | 6/20/2021 | 0 | 6/17/2021 | FALSE |
Here's the R script:
# 'dataset' holds the input data for this script
library(tidyverse)
library(lubridate)
start_date <- as.Date(as.POSIXct(parse_date_time('2018-10-04', orders="ymd")))
end_date <- as.Date(today(), format= "%Y-%m-%d")
date_range <- as.list(seq.Date(start_date, end_date, by = "day"))
for (i in seq_along(date_range)) {
dataset <- dataset %>%
dplyr::mutate(!!paste0(as.Date(start_date + i-1, format= "%Y-%m-%d")) := case_when(CompleteDate == as.Date(start_date + i-1, format= "%Y-%m-%d") ~ "ORDERED",
CreateDate == as.Date(start_date + i-1, format= "%Y-%m-%d") ~ "NEW",
CreateDate < as.Date(start_date + i-1, format= "%Y-%m-%d") & (is.na(CompleteDate) | CompleteDate > as.Date(start_date + i-1, format= "%Y-%m-%d")) ~ "InProcess"))
}
And here is the error:
I have tried changing the format of that input and have not gotten anywhere, and then I thought defining the date format might work but that did not either. Any help is appreciated!!
Solved! Go to Solution.
@Anonymous
Power bi somehow resturns "Microsft.OleDb.Date" as the result. Please refer to R script in Power BI returns date as Microsoft.OleDb.Date - Stack Overflow
1. As mentioned in the solution, first change the date type to Text type.
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"OldId", Int64.Type}, {"PartId", Int64.Type}, {"ProcessStepId", Int64.Type}, {"CreateDate", type datetime}, {"CompleteDate", type text}, {"Order", Int64.Type}, {"DueDate", type text}, {"Check", type text}}),
2. Use output instead of dataset, and add as.date() to convert it to date.
output <- dataset %>%
as.Date(start_date + i-1, format= ""%Y-%m-%d"") & (is.na(as.Date(CompleteDate)) |
as.Date(CompleteDate) > as.Date(start_date + i-1, format= ""%Y-%m-%d"")) ~ ""InProcess""))#(lf)}",[dataset=#"Changed Type"]),
3. The output will text and remembe rto change it to date type. Here is the full code:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("dcw9CsMwDAXgu3hOHP1Yku2tQztla7eQ+1+jKrjUpLbgwQNJ33EEFJKSc1gCeJJAMvHCHgLCFXRFeKFWzhVKlGLg49v28TnadEPy/rjtz3s4l68qvZqmqsaEMFbTQKVe5anKkWWiyr9qpVdprFqVEjNMVB2o2qs4VTUaclMbR3Dh7cefbw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, OldId = _t, PartId = _t, ProcessStepId = _t, CreateDate = _t, CompleteDate = _t, Order = _t, DueDate = _t, Check = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"OldId", Int64.Type}, {"PartId", Int64.Type}, {"ProcessStepId", Int64.Type}, {"CreateDate", type datetime}, {"CompleteDate", type text}, {"Order", Int64.Type}, {"DueDate", type text}, {"Check", type text}}),
#"Run R script" = R.Execute("# 'dataset' holds the input data for this script#(lf)library(tidyverse)#(lf)library(lubridate)#(lf)#(lf)start_date <- as.Date(as.POSIXct(parse_date_time('2018-10-04', orders=""ymd"")))#(lf)#(lf)end_date <- as.Date(today(), format= ""%Y-%m-%d"")#(lf)#(lf)date_range <- as.list(seq.Date(start_date, end_date, by = ""day""))#(lf)#(lf)#(lf)for (i in seq_along(date_range)) {#(lf)#(lf)#(lf)output <- dataset %>%#(lf)dplyr::mutate(!!paste0(as.Date(start_date + i-1, format= ""%Y-%m-%d"")) := case_when(as.Date(CompleteDate) == as.Date(start_date + i-1, format= ""%Y-%m-%d"") ~ ""ORDERED"",#(lf)as.Date(CreateDate) == as.Date(start_date + i-1, format= ""%Y-%m-%d"") ~ ""NEW"",#(lf)as.Date(CreateDate) < as.Date(start_date + i-1, format= ""%Y-%m-%d"") & (is.na(as.Date(CompleteDate)) | as.Date(CompleteDate) > as.Date(start_date + i-1, format= ""%Y-%m-%d"")) ~ ""InProcess""))#(lf)}",[dataset=#"Changed Type"]),
output = #"Run R script"{[Name="output"]}[Value],
#"Changed Type1" = Table.TransformColumnTypes(output,{{"CompleteDate", type date}, {"DueDate", type date}})
in
#"Changed Type1"
Paul Zheng _ Community Support Team
If this post helps, please Accept it as the solution to help the other members find it more quickly.
@Anonymous
Power bi somehow resturns "Microsft.OleDb.Date" as the result. Please refer to R script in Power BI returns date as Microsoft.OleDb.Date - Stack Overflow
1. As mentioned in the solution, first change the date type to Text type.
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"OldId", Int64.Type}, {"PartId", Int64.Type}, {"ProcessStepId", Int64.Type}, {"CreateDate", type datetime}, {"CompleteDate", type text}, {"Order", Int64.Type}, {"DueDate", type text}, {"Check", type text}}),
2. Use output instead of dataset, and add as.date() to convert it to date.
output <- dataset %>%
as.Date(start_date + i-1, format= ""%Y-%m-%d"") & (is.na(as.Date(CompleteDate)) |
as.Date(CompleteDate) > as.Date(start_date + i-1, format= ""%Y-%m-%d"")) ~ ""InProcess""))#(lf)}",[dataset=#"Changed Type"]),
3. The output will text and remembe rto change it to date type. Here is the full code:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("dcw9CsMwDAXgu3hOHP1Yku2tQztla7eQ+1+jKrjUpLbgwQNJ33EEFJKSc1gCeJJAMvHCHgLCFXRFeKFWzhVKlGLg49v28TnadEPy/rjtz3s4l68qvZqmqsaEMFbTQKVe5anKkWWiyr9qpVdprFqVEjNMVB2o2qs4VTUaclMbR3Dh7cefbw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, OldId = _t, PartId = _t, ProcessStepId = _t, CreateDate = _t, CompleteDate = _t, Order = _t, DueDate = _t, Check = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"OldId", Int64.Type}, {"PartId", Int64.Type}, {"ProcessStepId", Int64.Type}, {"CreateDate", type datetime}, {"CompleteDate", type text}, {"Order", Int64.Type}, {"DueDate", type text}, {"Check", type text}}),
#"Run R script" = R.Execute("# 'dataset' holds the input data for this script#(lf)library(tidyverse)#(lf)library(lubridate)#(lf)#(lf)start_date <- as.Date(as.POSIXct(parse_date_time('2018-10-04', orders=""ymd"")))#(lf)#(lf)end_date <- as.Date(today(), format= ""%Y-%m-%d"")#(lf)#(lf)date_range <- as.list(seq.Date(start_date, end_date, by = ""day""))#(lf)#(lf)#(lf)for (i in seq_along(date_range)) {#(lf)#(lf)#(lf)output <- dataset %>%#(lf)dplyr::mutate(!!paste0(as.Date(start_date + i-1, format= ""%Y-%m-%d"")) := case_when(as.Date(CompleteDate) == as.Date(start_date + i-1, format= ""%Y-%m-%d"") ~ ""ORDERED"",#(lf)as.Date(CreateDate) == as.Date(start_date + i-1, format= ""%Y-%m-%d"") ~ ""NEW"",#(lf)as.Date(CreateDate) < as.Date(start_date + i-1, format= ""%Y-%m-%d"") & (is.na(as.Date(CompleteDate)) | as.Date(CompleteDate) > as.Date(start_date + i-1, format= ""%Y-%m-%d"")) ~ ""InProcess""))#(lf)}",[dataset=#"Changed Type"]),
output = #"Run R script"{[Name="output"]}[Value],
#"Changed Type1" = Table.TransformColumnTypes(output,{{"CompleteDate", type date}, {"DueDate", type date}})
in
#"Changed Type1"
Paul Zheng _ Community Support Team
If this post helps, please Accept it as the solution to help the other members find it more quickly.
Thank you so much, this is definitely helping! However, it is not showing the "InProcess", "Ordered", or "New" statuses in the columns that were created, they're all null. It looks like yours is showing up correctly, so wondering what is different.
Columns showing correctly but all null:
Code (changed date columns to text prior to running):
# 'dataset' holds the input data for this script
library(tidyverse)
library(lubridate)
start_date <- as.Date(as.POSIXct(parse_date_time('2018-10-04', orders="ymd")))
end_date <- as.Date(as.POSIXct(parse_date_time('2018-10-07', orders="ymd")))
date_range <- as.list(seq.Date(start_date, end_date, by = "day"))
for (i in seq_along(date_range)) {
dataset<- dataset %>%
mutate(!!paste0(start_date + i-1) := case_when( as.Date(CompleteDate, format= "%Y-%m-%d") == as.Date(start_date + i-1, format= "%Y-%m-%d") ~ "ORDERED",
as.Date(CreateDate, format= "%Y-%m-%d") == as.Date(start_date + i-1, format= "%Y-%m-%d") ~ "NEW",
as.Date(CreateDate,format= "%Y-%m-%d") < as.Date(start_date + i-1, format= "%Y-%m-%d") & (is.na(as.Date(CompleteDate, format= "%Y-%m-%d")) | as.Date(CompleteDate, format= "%Y-%m-%d") > as.Date(start_date + i-1, format= "%Y-%m-%d")) ~ "InProcess"))
}
output <- dataset
I used output <- dataset at the end because if I have output in the loop, it only adds one column and I am looking to add one column for each date in the date range.
Actually, ended up getting it to work using someone's comment in Stack Overflow to change the Date columns to whole numbers, and then set an orgin to "1899-12-30". Thanks!!