Reputation: 31
I have a table in R that is built using this data frame:
Year <- c('2016','2017','2018','2016','2017','2018')
D <- c(0.6,0.57,.56,.41,.45,.85)
C <- c(.8,.9,.65,.8,.9,.65)
var <- c('a','a','a','b','b','b')
dat <- cbind.data.frame(var,Year,D,C)
My goal create a summary table with a header row for each year, then nest(apologies if this not the correct word here) fields D and E under said year: desired output
Upvotes: 1
Views: 1560
Reputation: 79358
Using base R, it is not quite true that you can produce the desired output. R dataframes do not allow for MultiIndex unless you use ftables
. The closses you could get is using dataframes is provided by the below solutions. If you dont mind using ftables
you could do:
# creating data table
Year <- as.factor(c('2016','2017','2018','2016','2017','2018'))
D <- c(0.6,0.57,.56,.41,.45,.85)
C <- c(.8,.9,.65,.8,.9,.65)
var <- c('a','a','a','b','b','b')
dat <- cbind.data.frame(var,Year,D,C)
# reformatting
tm <- c("D", "C") # the columns to change
a <- reshape(dat, list(tm), idvar = c("var", "Year"), dir = "long", times = tm))
ftable(xtabs(D~., a), row.vars = 1)
Year 2016 2017 2018
time C D C D C D
var
a 0.80 0.60 0.90 0.57 0.65 0.56
b 0.80 0.41 0.90 0.45 0.65 0.85
EDIT:
since you are using the KableExtra
package, You could do:
nm <- setNames(rep(1:2, c(2, length(unique(dat$Year)))), c(rep(" ", 2), levels(dat$Year)))
library(kableExtra)
dat %>%
reshape(idvar = "var", timevar = "Year", direction = "wide") %>%
setNames(gsub("[0-9.]+", "", names(.))) %>%
kable() %>%
kable_styling("striped") %>%
add_header_above(nm)
The result:
Upvotes: 1
Reputation: 887981
An option with pivot_wider
library(dplyr)
library(tidyr)
dat %>%
pivot_wider(names_from = Year, values_from = c(D, C))
# A tibble: 2 x 7
# var D_2016 D_2017 D_2018 C_2016 C_2017 C_2018
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 a 0.6 0.570 0.56 0.8 0.9 0.65
#2 b 0.41 0.45 0.85 0.8 0.9 0.65
Or using dcast
from data.table
library(data.table)
dcast(setDT(dat), var ~ Year, value.var = c("D", "C"))
# var D_2016 D_2017 D_2018 C_2016 C_2017 C_2018
#1: a 0.60 0.57 0.56 0.8 0.9 0.65
#2: b 0.41 0.45 0.85 0.8 0.9 0.65
Upvotes: 0
Reputation: 1081
You can't have a multi-row index in R. This might work:
reshape(dat, idvar = "var", timevar = "Year", direction = "wide")
var D.2016 C.2016 D.2017 C.2017 D.2018 C.2018
1 a 0.60 0.8 0.57 0.9 0.56 0.65
4 b 0.41 0.8 0.45 0.9 0.85 0.65
Upvotes: 0