build_joined_dataframe Subroutine

private subroutine build_joined_dataframe(df1, df2, indices1, indices2, num_rows, result_df)

Helper subroutine to build joined dataframe from match indices

@param[in] df1 First dataframe @param[in] df2 Second dataframe @param[in] indices1 Row indices from df1 (-1 means no match) @param[in] indices2 Row indices from df2 (-1 means no match) @param[in] num_rows Number of rows in result @param[out] result_df Resulting joined dataframe

Arguments

Type IntentOptional Attributes Name
type(data_frame), intent(in) :: df1
type(data_frame), intent(in) :: df2
integer, intent(in), dimension(:) :: indices1
integer, intent(in), dimension(:) :: indices2
integer, intent(in) :: num_rows
type(data_frame), intent(out) :: result_df

Source Code

    subroutine build_joined_dataframe(df1, df2, indices1, indices2, num_rows, result_df)
        type(data_frame), intent(in) :: df1, df2
        integer, dimension(:), intent(in) :: indices1, indices2
        integer, intent(in) :: num_rows
        type(data_frame), intent(out) :: result_df

        integer :: i, j, row, col_idx, dtype
        real(rk), dimension(:), allocatable :: real_col
        integer(ik), dimension(:), allocatable :: int_col
        logical, dimension(:), allocatable :: log_col
        character(len=:), allocatable :: char_col(:)
        complex(rk), dimension(:), allocatable :: cmplx_col
        character(len=100) :: header_name

        call result_df % new(max(df1 % get_max_char_len(), df2 % get_max_char_len()))

        ! Add columns from df1
        do i = 1, df1 % ncols()
            dtype = df1 % dtype(i)

            select case (dtype)
            case (REAL_NUM)
                allocate (real_col(num_rows))
                do row = 1, num_rows
                    if (indices1(row) > 0) then
                        real_col(row) = df_get_val_real(df1, indices1(row), i)
                    else
                        real_col(row) = 0.0_rk  ! NULL value
                    end if
                end do
                if (df1 % get_with_headers()) then
                    header_name = df1 % header(i)
                    call df_append_real(result_df, real_col, trim(header_name))
                else
                    call df_append_real(result_df, real_col)
                end if
                deallocate (real_col)

            case (INTEGER_NUM)
                allocate (int_col(num_rows))
                do row = 1, num_rows
                    if (indices1(row) > 0) then
                        int_col(row) = df_get_val_integer(df1, indices1(row), i)
                    else
                        int_col(row) = 0_ik  ! NULL value
                    end if
                end do
                if (df1 % get_with_headers()) then
                    header_name = df1 % header(i)
                    call df_append_integer(result_df, int_col, trim(header_name))
                else
                    call df_append_integer(result_df, int_col)
                end if
                deallocate (int_col)

            case (LOGICAL_NUM)
                allocate (log_col(num_rows))
                do row = 1, num_rows
                    if (indices1(row) > 0) then
                        log_col(row) = df_get_val_logical(df1, indices1(row), i)
                    else
                        log_col(row) = .false.  ! NULL value
                    end if
                end do
                if (df1 % get_with_headers()) then
                    header_name = df1 % header(i)
                    call df_append_logical(result_df, log_col, trim(header_name))
                else
                    call df_append_logical(result_df, log_col)
                end if
                deallocate (log_col)

            case (CHARACTER_NUM)
                allocate (character(len=df1 % get_max_char_len()) :: char_col(num_rows))
                do row = 1, num_rows
                    if (indices1(row) > 0) then
                        char_col(row) = df_get_val_character(df1, indices1(row), i)
                    else
                        char_col(row) = "NULL"
                    end if
                end do
                if (df1 % get_with_headers()) then
                    header_name = df1 % header(i)
                    call df_append_character(result_df, char_col, trim(header_name))
                else
                    call df_append_character(result_df, char_col)
                end if
                deallocate (char_col)

            case (COMPLEX_NUM)
                allocate (cmplx_col(num_rows))
                do row = 1, num_rows
                    if (indices1(row) > 0) then
                        cmplx_col(row) = df_get_val_complex(df1, indices1(row), i)
                    else
                        cmplx_col(row) = cmplx(0.0_rk, 0.0_rk, rk)
                    end if
                end do
                if (df1 % get_with_headers()) then
                    header_name = df1 % header(i)
                    call df_append_complex(result_df, cmplx_col, trim(header_name))
                else
                    call df_append_complex(result_df, cmplx_col)
                end if
                deallocate (cmplx_col)
            end select
        end do

        ! Add columns from df2
        do i = 1, df2 % ncols()
            dtype = df2 % dtype(i)

            select case (dtype)
            case (REAL_NUM)
                allocate (real_col(num_rows))
                do row = 1, num_rows
                    if (indices2(row) > 0) then
                        real_col(row) = df_get_val_real(df2, indices2(row), i)
                    else
                        real_col(row) = 0.0_rk
                    end if
                end do
                if (df2 % get_with_headers()) then
                    header_name = df2 % header(i)
                    call df_append_real(result_df, real_col, trim(header_name)//"_right")
                else
                    call df_append_real(result_df, real_col)
                end if
                deallocate (real_col)

            case (INTEGER_NUM)
                allocate (int_col(num_rows))
                do row = 1, num_rows
                    if (indices2(row) > 0) then
                        int_col(row) = df_get_val_integer(df2, indices2(row), i)
                    else
                        int_col(row) = 0_ik
                    end if
                end do
                if (df2 % get_with_headers()) then
                    header_name = df2 % header(i)
                    call df_append_integer(result_df, int_col, trim(header_name)//"_right")
                else
                    call df_append_integer(result_df, int_col)
                end if
                deallocate (int_col)

            case (LOGICAL_NUM)
                allocate (log_col(num_rows))
                do row = 1, num_rows
                    if (indices2(row) > 0) then
                        log_col(row) = df_get_val_logical(df2, indices2(row), i)
                    else
                        log_col(row) = .false.
                    end if
                end do
                if (df2 % get_with_headers()) then
                    header_name = df2 % header(i)
                    call df_append_logical(result_df, log_col, trim(header_name)//"_right")
                else
                    call df_append_logical(result_df, log_col)
                end if
                deallocate (log_col)

            case (CHARACTER_NUM)
                allocate (character(len=df2 % get_max_char_len()) :: char_col(num_rows))
                do row = 1, num_rows
                    if (indices2(row) > 0) then
                        char_col(row) = df_get_val_character(df2, indices2(row), i)
                    else
                        char_col(row) = "NULL"
                    end if
                end do
                if (df2 % get_with_headers()) then
                    header_name = df2 % header(i)
                    call df_append_character(result_df, char_col, trim(header_name)//"_right")
                else
                    call df_append_character(result_df, char_col)
                end if
                deallocate (char_col)

            case (COMPLEX_NUM)
                allocate (cmplx_col(num_rows))
                do row = 1, num_rows
                    if (indices2(row) > 0) then
                        cmplx_col(row) = df_get_val_complex(df2, indices2(row), i)
                    else
                        cmplx_col(row) = cmplx(0.0_rk, 0.0_rk, rk)
                    end if
                end do
                if (df2 % get_with_headers()) then
                    header_name = df2 % header(i)
                    call df_append_complex(result_df, cmplx_col, trim(header_name)//"_right")
                else
                    call df_append_complex(result_df, cmplx_col)
                end if
                deallocate (cmplx_col)
            end select
        end do
    end subroutine build_joined_dataframe