Concatenate two data frames vertically (rows) or horizontally (columns)
@param[in] df1 First data frame @param[in] df2 Second data frame @param[in] axis 0 for vertical (stack rows), 1 for horizontal (add columns) @return Concatenated data frame
Note
For axis=0 (vertical), both data frames must have same number of columns
Note
For axis=1 (horizontal), both data frames must have same number of rows
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(data_frame), | intent(in) | :: | df1 | |||
type(data_frame), | intent(in) | :: | df2 | |||
integer, | intent(in) | :: | axis |
function df_concat(df1, df2, axis) result(result_df) type(data_frame), intent(in) :: df1, df2 integer, intent(in) :: axis type(data_frame) :: result_df integer :: i, j, dtype character(len=100) :: header_name real(rk), dimension(:), allocatable :: real_col1, real_col2, real_combined, real_col integer(ik), dimension(:), allocatable :: int_col1, int_col2, int_combined, int_col logical, dimension(:), allocatable :: log_col1, log_col2, log_combined, log_col character(len=:), allocatable :: char_col1(:), char_col2(:), char_combined(:), char_col(:) complex(rk), dimension(:), allocatable :: cmplx_col1, cmplx_col2, cmplx_combined, cmplx_col if (axis == 0) then ! Vertical concatenation (stack rows) if (df1 % ncols() /= df2 % ncols()) then print *, "Error: DataFrames must have same number of columns" call result_df % new() return end if call result_df % new(max(df1 % get_max_char_len(), df2 % get_max_char_len())) do i = 1, df1 % ncols() dtype = df1 % dtype(i) select case (dtype) case (REAL_NUM) real_col1 = df_get_col_real(df1, i) real_col2 = df_get_col_real(df2, i) allocate (real_combined(size(real_col1) + size(real_col2))) real_combined(1:size(real_col1)) = real_col1 real_combined(size(real_col1) + 1:) = real_col2 if (df1 % get_with_headers()) then header_name = df1 % header(i) call df_append_real(result_df, real_combined, trim(header_name)) else call df_append_real(result_df, real_combined) end if deallocate (real_col1, real_col2, real_combined) case (INTEGER_NUM) int_col1 = df_get_col_integer(df1, i) int_col2 = df_get_col_integer(df2, i) allocate (int_combined(size(int_col1) + size(int_col2))) int_combined(1:size(int_col1)) = int_col1 int_combined(size(int_col1) + 1:) = int_col2 if (df1 % get_with_headers()) then header_name = df1 % header(i) call df_append_integer(result_df, int_combined, trim(header_name)) else call df_append_integer(result_df, int_combined) end if deallocate (int_col1, int_col2, int_combined) case (LOGICAL_NUM) log_col1 = df_get_col_logical(df1, i) log_col2 = df_get_col_logical(df2, i) allocate (log_combined(size(log_col1) + size(log_col2))) log_combined(1:size(log_col1)) = log_col1 log_combined(size(log_col1) + 1:) = log_col2 if (df1 % get_with_headers()) then header_name = df1 % header(i) call df_append_logical(result_df, log_combined, trim(header_name)) else call df_append_logical(result_df, log_combined) end if deallocate (log_col1, log_col2, log_combined) case (CHARACTER_NUM) char_col1 = df_get_col_character(df1, i) char_col2 = df_get_col_character(df2, i) allocate (character(len=max(len(char_col1), len(char_col2))) :: char_combined(size(char_col1) + size(char_col2))) char_combined(1:size(char_col1)) = char_col1 char_combined(size(char_col1) + 1:) = char_col2 if (df1 % get_with_headers()) then header_name = df1 % header(i) call df_append_character(result_df, char_combined, trim(header_name)) else call df_append_character(result_df, char_combined) end if deallocate (char_col1, char_col2, char_combined) case (COMPLEX_NUM) cmplx_col1 = df_get_col_complex(df1, i) cmplx_col2 = df_get_col_complex(df2, i) allocate (cmplx_combined(size(cmplx_col1) + size(cmplx_col2))) cmplx_combined(1:size(cmplx_col1)) = cmplx_col1 cmplx_combined(size(cmplx_col1) + 1:) = cmplx_col2 if (df1 % get_with_headers()) then header_name = df1 % header(i) call df_append_complex(result_df, cmplx_combined, trim(header_name)) else call df_append_complex(result_df, cmplx_combined) end if deallocate (cmplx_col1, cmplx_col2, cmplx_combined) end select end do else if (axis == 1) then ! Horizontal concatenation (add columns) if (df1 % nrows() /= df2 % nrows()) then print *, "Error: DataFrames must have same number of rows" call result_df % new() return end if result_df = df_copy(df1) ! Add columns from df2 do i = 1, df2 % ncols() dtype = df2 % dtype(i) select case (dtype) case (REAL_NUM) real_col = df_get_col_real(df2, i) if (df2 % get_with_headers()) then header_name = df2 % 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) int_col = df_get_col_integer(df2, i) if (df2 % get_with_headers()) then header_name = df2 % 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) log_col = df_get_col_logical(df2, i) if (df2 % get_with_headers()) then header_name = df2 % 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) char_col = df_get_col_character(df2, i) if (df2 % get_with_headers()) then header_name = df2 % 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) cmplx_col = df_get_col_complex(df2, i) if (df2 % get_with_headers()) then header_name = df2 % 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 else print *, "Error: axis must be 0 (vertical) or 1 (horizontal)" call result_df % new() end if end function df_concat