df_equals Function

public function df_equals(df1, df2) result(is_equal)

Check if two dataframes are identical

Compares shape, headers, column types, and all values

@param df1 First data frame @param df2 Second data frame @return .true. if dataframes are identical, .false. otherwise

Arguments

Type IntentOptional Attributes Name
type(data_frame), intent(in) :: df1
type(data_frame), intent(in) :: df2

Return Value logical


Source Code

    function df_equals(df1, df2) result(is_equal)
        type(data_frame), intent(in) :: df1, df2
        logical :: is_equal
        integer :: i, j
        real(rk), dimension(:), allocatable :: col1_real, col2_real
        integer(ik), dimension(:), allocatable :: col1_int, col2_int
        logical, dimension(:), allocatable :: col1_log, col2_log
        character(len=:), allocatable :: val1_char, val2_char
        complex(rk), dimension(:), allocatable :: col1_cplx, col2_cplx

        is_equal = .false.

        ! Check dimensions
        if (df1 % nrows() /= df2 % nrows()) return
        if (df1 % ncols() /= df2 % ncols()) return

        ! Check headers
        do i = 1, df1 % ncols()
            if (df1 % header(i) /= df2 % header(i)) return
        end do

        ! Check column types
        do i = 1, df1 % ncols()
            if (df1 % dtype(i) /= df2 % dtype(i)) return
        end do

        ! Check values column by column
        do i = 1, df1 % ncols()
            select case (df1 % dtype(i))
            case (REAL_NUM)
                col1_real = df_get_col_real(df1, i)
                col2_real = df_get_col_real(df2, i)
                do j = 1, size(col1_real)
                    if (abs(col1_real(j) - col2_real(j)) > 1.0e-10_rk) then
                        deallocate (col1_real, col2_real)
                        return
                    end if
                end do
                deallocate (col1_real, col2_real)

            case (INTEGER_NUM)
                col1_int = df_get_col_integer(df1, i)
                col2_int = df_get_col_integer(df2, i)
                if (any(col1_int /= col2_int)) then
                    deallocate (col1_int, col2_int)
                    return
                end if
                deallocate (col1_int, col2_int)

            case (LOGICAL_NUM)
                col1_log = df_get_col_logical(df1, i)
                col2_log = df_get_col_logical(df2, i)
                if (any(col1_log .neqv. col2_log)) then
                    deallocate (col1_log, col2_log)
                    return
                end if
                deallocate (col1_log, col2_log)

            case (CHARACTER_NUM)
                do j = 1, df1 % nrows()
                    val1_char = df_get_val_character(df1, j, i)
                    val2_char = df_get_val_character(df2, j, i)
                    if (val1_char /= val2_char) then
                        deallocate (val1_char, val2_char)
                        return
                    end if
                    deallocate (val1_char, val2_char)
                end do

            case (COMPLEX_NUM)
                col1_cplx = df_get_col_complex(df1, i)
                col2_cplx = df_get_col_complex(df2, i)
                do j = 1, size(col1_cplx)
                    if (abs(col1_cplx(j) - col2_cplx(j)) > 1.0e-10_rk) then
                        deallocate (col1_cplx, col2_cplx)
                        return
                    end if
                end do
                deallocate (col1_cplx, col2_cplx)
            end select
        end do

        ! All checks passed
        is_equal = .true.
    end function df_equals