tidyr: conversión de largo a ancho, usando pivot_wide() en dos columnas en R

CorePress2024-01-24  11

Me gustaría transformar mis datos de formato largo a ancho según los valores de dos columnas. ¿Cómo puedo hacer esto usando tidyverse?

Dput actualizado

structure(list(Country = c("Algeria", "Benin", "Ghana", "Algeria", 
                       "Benin", "Ghana", "Algeria", "Benin", "Ghana"
), Indicator = c("Indicator 1", 
             "Indicator 1", 
             "Indicator 1", 
             "Indicator 2", 
             "Indicator 2", 
             "Indicator 2",
             "Indicator 3", 
             "Indicator 3", 
             "Indicator 3"
), Status = c("Actual", "Forecast", "Target", "Actual", "Forecast", 
          "Target", "Actual", "Forecast", "Target"), Value = c(34, 15, 5, 
                                                               28, 5, 2, 43, 5, 
                                                               1)), row.names 
= c(NA, -9L), class = c("tbl_df", "tbl", "data.frame"))


    Country Indicator   Status   Value
    <chr>   <chr>       <chr>    <dbl>
1 Algeria Indicator 1 Actual      34
2 Benin   Indicator 1 Forecast    15
3 Ghana   Indicator 1 Target       5
4 Algeria Indicator 2 Actual      28
5 Benin   Indicator 2 Forecast     5
6 Ghana   Indicator 2 Target       2
7 Algeria Indicator 3 Actual      43
8 Benin   Indicator 3 Forecast     5
9 Ghana   Indicator 3 Target       1

Resultado esperado

Country Indicator1_Actual Indicator1_Forecast Indicator1_Target Indicator2_Actual

Algeria       34                    15                 5           28

etc

¡Agradezco cualquier consejo!

foo <- data %>% pivot_wider(names_from = c("Indicator","Status"), values_from = "Value") 

¡Funciona perfectamente!



------------------------------------

Creo que el error está en el comando pivot_wider() datos %>% pivot_wider(names_from = Indicador, valores_from = c(Indicador, Estado))

Apuesto a que no puedes usar la misma columna para nombres y valores.

Prueba este código

data %>% pivot_wider(names_from = c(Indicator, Status), values_from = Value))

Explicación: Como desea que los nombres de las columnas sean Indicador 1_Actual, necesita ambas columnas.indicador y estado entrando en su nombres_de

Sería útil si proporcionara datos de ejemplo y el resultado esperado. Pero probé esto con mis datos ficticios y me dio el resultado esperado:

Datos:

# A tibble: 4 x 4
     a1    a2 a3       a4
  <int> <int> <chr> <dbl>
1     1     5 s        10
2     2     4 s        20
3     3     3 n        30
4     4     2 n        40

Llamada: a %>% pivot_wider(names_from = c(a2, a3), value_from = a4)

Salida:

# A tibble: 4 x 5
     a1 `5_s` `4_s` `3_n` `2_n`
  <int> <dbl> <dbl> <dbl> <dbl>
1     1    10    NA    NA    NA
2     2    NA    20    NA    NA
3     3    NA    NA    30    NA
4     4    NA    NA    NA    40

Datos aquí si quieres reproducir

structure(list(a1 = 1:4, a2 = 5:2, a3 = c("s", "s", "n", "n"), 
    a4 = c(10, 20, 30, 40)), row.names = c(NA, -4L), class = c("tbl_df", 
"tbl", "data.frame"))

Editar: para la pregunta editada después de probar el comando pivot_wider() correcto. Parece que sus datos podrían tener duplicados, en cuyo caso el resultado que está viendo tendría sentido. Le sugiero que intente averiguar si sus datos en realidad tienen duplicados usando el filtro (País == .., Indicador == .., Estado == ..)

6

Actualicé la pregunta, cometí un error, columna de valor agregado

- Anakin Skywalker

27/03/2021 a las 21:01

1

Gracias @AnakinSkywalker, la columna Valor me permitió descubrir lo que intentabas hacer. ¿Podrías publicar tus datos reales con dput(.your data frame) o una versión reducida de tus datos con head(data frame) para que pueda reproducir tu problema?

- Prashant Bharadwaj

27/03/2021 a las 21:11

1

Parece que estás excluyendo algunas columnas en tu llamada a pivot_wider, por lo que las nuevas columnas no tienen valores únicos para cada país. Por lo tanto, se espera hacer listas con c(.,.,.). Asegúrese de pasar todos sus datos a pivot_wider() y no pase solo la región al parámetro id_cols

- Prashant Bharadwaj

27 de marzo de2021 a las 21:18

Creé un ejemplo normal para ti

- Anakin Skywalker

27/03/2021 a las 21:23

1

Mmmm. No puedo encontrar ningún problema con el subconjunto de datos que ha publicado. Yo diría que intente averiguar si sus datos realmente tienen duplicados usando el filtro (País == .., Indicador == .., Estado == ..)

- Prashant Bharadwaj

27/03/2021 a las 21:53



------------------------------------

Esto se puede lograr llamando a ambas columnas para que giren más en el argumento nombres_de en pivot_wider().

data %>% 
  pivot_wider(names_from = c("Indicator","Status"),
              values_from = "Value")

Resultado

  Country `Indicator 1_Ac… `Indicator 1_Fo… `Indicator 1_Ta… `Indicator 2_Ac… `Indicator 2_Fo…
  <chr>              <dbl>            <dbl>            <dbl>            <dbl>            <dbl>
1 Algeria               34               15                5               28                5

11

1

¿Posiblemente porque tienes más de un país?

- Ali

27/03/2021 a las 21:35

Sí, tengo más de un país

- Anakin Skywalker

27/03/2021 a las 21:37

1

En realidad, esto debería funcionar sin varios países. ¿Tiene un mensaje de error emergente? He editado mi respuesta para mostrar el resultado

- Ali

27/03/2021 a las 21:39

1

Podrían ser varias cosas. En primer lugar, los nombres de las columnas no son los más fáciles de usar en R. Intente ceñirse a '_' a en lugar de un espacio. Tus datos reales deben ser diferentes al ejemplo que has dado.

- Ali

27/03/2021 a las 21:47

1

¡Gracias por tu tiempo! Acepté otra respuesta porque él era ele primero cronológicamente. ¡Pero aprecio mucho tu tiempo!

- Anakin Skywalker

27/03/2021 a las 22:04

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare