R ¿Reformar el marco de datos de formato largo a ancho?
dataframe reshape (3)
¿Cuál es la mejor manera de convertir el marco de datos a continuación de formato largo a ancho? Intenté usar remodelación pero no obtuve los resultados deseados.
2015 PROD A test1
2015 PROD A blue
2015 PROD A 50
2015 PROD A 66
2015 PROD A 66
2018 PROD B test2
2018 PROD B yellow
2018 PROD B 70
2018 PROD B 88.8
2018 PROD B 88.8
2018 PROD A test3
2018 PROD A red
2018 PROD A 55
2018 PROD A 88
2018 PROD A 90
En aras de la integridad, aquí hay una solución que utiliza la conveniente función
rowid()
.
El punto crucial de la pregunta es que la remodelación depende únicamente de la
posición
de la
fila
de
value
dentro de cada grupo (
year
,
product
).
rowid(year, product)
numera las filas dentro de cada grupo.
Entonces, remodelar se convierte esencialmente en una sola línea:
library(data.table)
dcast(setDT(df1), year + product ~ rowid(year, product, prefix = "col_"))
year product col_1 col_2 col_3 col_4 col_5 1: 2015 PROD A test1 blue 50 66 66 2: 2018 PROD A test3 red 55 88 90 3: 2018 PROD B test2 yellow 70 88.8 88.8
Tenga en cuenta que
rowid()
toma un parámetro de
prefix
para asegurarse de que los nombres de las columnas resultantes sean sintácticamente correctos.
Advertencia:
esta solución supone que el
year
y el
product
forman una
clave única
para cada grupo.
Datos
Los datos se leen como publicados por el OP sin ninguna modificación a los datos. Sin embargo, esto requiere unas pocas líneas de post-procesamiento:
library(data.table)
df1 <- fread("
2015 PROD A test1
2015 PROD A blue
2015 PROD A 50
2015 PROD A 66
2015 PROD A 66
2018 PROD B test2
2018 PROD B yellow
2018 PROD B 70
2018 PROD B 88.8
2018 PROD B 88.8
2018 PROD A test3
2018 PROD A red
2018 PROD A 55
2018 PROD A 88
2018 PROD A 90",
header = FALSE, col.names = c("year", "product", "value"), drop = 2L)[
, product := paste("PROD", product)][]
Estás buscando la función de
dcast
.
Utilizado como
dcast(data, col1 + col2 ~ col3)
Esta pregunta también puede ser un duplicado, por lo que puede eliminarse.
Una posible solución es esta
library(tidyverse)
df = read.table(text = "
year prod value
2015 PRODA test1
2015 PRODA blue
2015 PRODA 50
2015 PRODA 66
2015 PRODA 66
2018 PRODB test2
2018 PRODB yellow
2018 PRODB 70
2018 PRODB 88.8
2018 PRODB 88.8
2018 PRODA test3
2018 PRODA red
2018 PRODA 55
2018 PRODA 88
2018 PRODA 90
", header=T, stringsAsFactors=F)
df %>%
group_by(year, prod) %>% # for each year and prod combination
mutate(id = paste0("new_col_", row_number())) %>% # enumerate rows (this will be used as column names in the reshaped version)
ungroup() %>% # forget the grouping
spread(id, value) # reshape
# # A tibble: 3 x 7
# year prod new_col_1 new_col_2 new_col_3 new_col_4 new_col_5
# <int> <chr> <chr> <chr> <chr> <chr> <chr>
# 1 2015 PRODA test1 blue 50 66 66
# 2 2018 PRODA test3 red 55 88 90
# 3 2018 PRODB test2 yellow 70 88.8 88.8