Home > Software engineering >  collapsing rows into a single row and filling NA's
collapsing rows into a single row and filling NA's

Time:04-06

I have a data frame which looks like:

  ...1                    ...2  ...3        ...4  ...5  ...6  ...7        ...8  ...9  ...10 ...11       ...12 ...13 ...14 ...15      
  <chr>                   <lgl> <chr>       <chr> <chr> <chr> <chr>       <chr> <chr> <chr> <chr>       <chr> <chr> <chr> <chr>      
1 (*) Datos provisionales NA    NA          NA    NA    NA    NA          NA    NA    NA    NA          NA    NA    NA    NA         
2 NA                      NA    Año 2004    NA    NA    NA    Año 2005    NA    NA    NA    Año 2006    NA    NA    NA    Año 2007   
3 NA                      NA    (trimestre) NA    NA    NA    (trimestre) NA    NA    NA    (trimestre) NA    NA    NA    (trimestre)
4 NA                      NA    1º          2º    3º    4º    1º          2º    3º    4º    1º          2º    3º    4º    1º         
5 ANDALUCÍA               NA    NA          NA    NA    NA    NA          NA    NA    NA    NA          NA    NA    NA    NA         
6 Almería                 NA    NA          NA    NA    NA    NA          NA    NA    NA    NA          NA    NA    NA    NA

What I am trying to do is to do:

  1. Spread the Año 2004 across 3 NA columns - until Año 2005, then do the same for Año 2005 and so on.
  2. Collapse row c(3, 4, 5) into a single row.

Data:

df = structure(list(...1 = c("(*) Datos provisionales", NA, NA, NA, 
"ANDALUCÍA", "Almería"), ...2 = c(NA, NA, NA, NA, NA, NA), 
    ...3 = c(NA, "Año 2004", "(trimestre)", "1º", NA, NA), 
    ...4 = c(NA, NA, NA, "2º", NA, NA), ...5 = c(NA, NA, NA, 
    "3º", NA, NA), ...6 = c(NA, NA, NA, "4º", NA, NA), ...7 = c(NA, 
    "Año 2005", "(trimestre)", "1º", NA, NA), ...8 = c(NA, 
    NA, NA, "2º", NA, NA), ...9 = c(NA, NA, NA, "3º", NA, NA
    ), ...10 = c(NA, NA, NA, "4º", NA, NA), ...11 = c(NA, "Año 2006", 
    "(trimestre)", "1º", NA, NA), ...12 = c(NA, NA, NA, "2º", 
    NA, NA), ...13 = c(NA, NA, NA, "3º", NA, NA), ...14 = c(NA, 
    NA, NA, "4º", NA, NA), ...15 = c(NA, "Año 2007", "(trimestre)", 
    "1º", NA, NA)), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

CodePudding user response:

For your first problem you can use the function na.locf with an apply to fill the upcoming values with the before values in a certain row:

df[2,] <- t(apply(df[2,], 1, function(x) na.locf(x, fromLast = F, na.rm = F)))

Output:

# A tibble: 6 × 15
  ...1                    ...2  ...3        ...4     ...5     ...6     ...7        ...8     ...9     ...10    ...11       ...12    ...13    ...14 ...15
  <chr>                   <chr> <chr>       <chr>    <chr>    <chr>    <chr>       <chr>    <chr>    <chr>    <chr>       <chr>    <chr>    <chr> <chr>
1 (*) Datos provisionales NA    NA          NA       NA       NA       NA          NA       NA       NA       NA          NA       NA       NA    NA   
2 NA                      NA    Año 2004    Año 2004 Año 2004 Año 2004 Año 2005    Año 2005 Año 2005 Año 2005 Año 2006    Año 2006 Año 2006 Año … Año …
3 NA                      NA    (trimestre) NA       NA       NA       (trimestre) NA       NA       NA       (trimestre) NA       NA       NA    (tri…
4 NA                      NA    1º          2º       3º       4º       1º          2º       3º       4º       1º          2º       3º       4º    1º   
5 ANDALUCÍA               NA    NA          NA       NA       NA       NA          NA       NA       NA       NA          NA       NA       NA    NA   
6 Almería                 NA    NA          NA       NA       NA       NA          NA       NA       NA       NA          NA       NA       NA    NA   

As you can see the values are filled. For your second problem I am not sure if it is a problem when you overwrite values in your three rows, because that is the case. You can use this code:

coalesce_by_column <- function(df) {
  return(dplyr::coalesce(!!! as.list(df)))
}


df[c(3:5),] <-df[c(3:5),] %>% 
  group_by(`...2`) %>% 
  summarise_all(coalesce_by_column)

df <- df %>% distinct()
df

Output:

# A tibble: 4 × 15
  ...1                    ...2      ...3        ...4     ...5     ...6     ...7        ...8     ...9     ...10    ...11       ...12   ...13 ...14 ...15
  <chr>                   <chr>     <chr>       <chr>    <chr>    <chr>    <chr>       <chr>    <chr>    <chr>    <chr>       <chr>   <chr> <chr> <chr>
1 (*) Datos provisionales NA        NA          NA       NA       NA       NA          NA       NA       NA       NA          NA      NA    NA    NA   
2 NA                      NA        Año 2004    Año 2004 Año 2004 Año 2004 Año 2005    Año 2005 Año 2005 Año 2005 Año 2006    Año 20… Año … Año … Año …
3 NA                      ANDALUCÍA (trimestre) 2º       3º       4º       (trimestre) 2º       3º       4º       (trimestre) 2º      3º    4º    (tri…
4 Almería                 NA        NA          NA       NA       NA       NA          NA       NA       NA       NA          NA      NA    NA    NA  
  • Related