3
\$\begingroup\$

Is there a more elegant way to ensure that colnames(output) of a output R dataframe retains the original column variable names in the referenced sample dataset data? So that I can eliminate the 2 gsub() lines of code, which rename my column names back to my original variable names. My R code, which can be run, is as follows

library(mvtnorm)
library(tidyverse)
muvec = apply(data, 2, mean) #data is passed as R dataframe
sigma = cov(data)
df = 10
n = 10
output <- as.data.frame(
        lapply(1:n, function(x) rep(muvec, each=10) + rmvt(10, sigma=sigma, df=df))) %>%
        select (sort(names(.)))
#looped function output assigns arbitrary variable names X1 and X2, instead of original variable names apple and pear
colnames(output) = gsub("X1", "apple", colnames(output))
colnames(output) = gsub("X2", "pear", colnames(output))
print(output)

data as follows

+-------+-------+
| apple | pear  |
+-------+-------+
|  0.18 |  0.05 |
|  0.22 |  0.03 |
|  0.21 |  0.03 |
|  0.11 |     0 |
|  0.15 |  0.03 |
|  0.13 |  0.01 |
|  0.03 |  0.01 |
|     0 |     0 |
| -0.06 | -0.01 |
| -0.09 | -0.02 |
+-------+-------+
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The most efficient way that I can think of is creating a function with rmvt which takes an additional argument to decide whether column names should be assigned based on the input (i.e. sigma) or not. If TRUE, before returning the results of rmvt function, it assigns the original names. See below (I used airquality dataset to make a reproducible example);

library(mvtnorm)
library(dplyr)

dat <- na.omit(datasets::airquality)[1:2,1:2]

muvec = apply(dat, 2, mean) #data is passed as R dataframe
sigma = cov(dat)
df = 10
n = 2

rmvt.names <- function(n, sigma = diag(2), df = 1, delta = rep(0, nrow(sigma)),
                       type = c("shifted", "Kshirsagar"), names = FALSE){
  out <- rmvt(n, sigma, df, delta, type)
  if (names) { colnames(out) <- colnames(sigma) }
  return(out)
}

lapply(1:n, function(x) 
            rep(muvec, each=10) + rmvt.names(10, sigma=sigma, df=df, names = T)) %>%
  as.data.frame() %>% 
  select (sort(names(.)))

#>       Ozone  Ozone.1    Solar.R  Solar.R.1
#> 1  37.47822 45.06226 139.286427 248.496571
#> 2  40.59224 42.78024 184.128243 215.635423
#> 3  33.03107 35.89953  75.247397 116.553211
#> 4  28.07207 28.48342   3.837864   9.761237
#> 5  38.15097 39.46869 148.974039 167.949166
#> 6  44.04143 42.68460 233.796536 214.258203
#> 7  36.54224 40.53313 125.808217 183.277053
#> 8  37.37606 38.77892 137.815314 158.016502
#> 9  43.99939 37.11836 233.191196 134.104332
#> 10 37.63792 32.28113 141.586044  64.448253

Created on 2020-05-06 by the reprex package (v0.3.0)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.