I have a vector say x <- c('a','b','c')

now I want to create an empty dataframe with column names as those in x. Values in x can be any character value, doesn't need to be a,b,c necessarily.

Hi,

Here is one way:

```
x = c("A", "B", "C")
myData = as.data.frame(matrix(numeric(),nrow = 0, ncol = length(x)))
colnames(myData) = x
myData
[1] A B C
<0 rows> (or 0-length row.names)
```

Question: why do you want to do this?

Hope this helps,

PJ

to add to PJ's solution:

you can also declare the colnames while constructing the matrix.

```
x <- c('a','b','c')
df <- as.data.frame(
matrix(ncol = length(x), nrow=0,
dimnames = list(NULL,x))
)
```

the dimnames argument must be a list of 2 vectors, first the rownames, then the colnames

I don't know why, but I got completely engrossed in code golfing this question. The most succinct I've been able to come up with are

```
x <- c("A", "B", "C")
df <- as.data.frame(sapply(x, function(x) numeric()))
df <- as.data.frame(vapply(x, function(x) numeric(), numeric()))
df <- as.data.frame(replicate(length(x), numeric()), col.names = x)
df <- as.data.frame(matrix(ncol = length(x), nrow=0, dimnames = list(NULL,x)))
df <- as.data.frame(matrix(numeric(),nrow = 0, ncol = length(x))); names(df) <- x
```

But succinct doesn't translate into efficient. I timed this over data frames from 1 to 500 columns (why anyone would ever make 500 columns of a data frame like this, I don't know, but let's not have reality interfere with ridiculous fun)

The best performer ends up being

```
df <- as.data.frame(matrix(ncol = length(x), nrow=0, dimnames = list(NULL,x)))`
```

in case you're really desperate to save yourself a few microseconds. (and I might need a better hobby)

```
library(dplyr)
library(tidyr)
library(ggplot2)
bench_fun <- function(x){
x <- sprintf("X%s", seq_len(x))
microbenchmark(
sapply = df <- as.data.frame(sapply(x, function(x) numeric())),
vapply = df <- as.data.frame(vapply(x, function(x) numeric(), numeric())),
replicate = df <- as.data.frame(replicate(length(x), numeric()), col.names = x),
name_with = df <- as.data.frame(matrix(ncol = length(x), nrow=0, dimnames = list(NULL,x))),
name_separately = {df <- as.data.frame(matrix(numeric(),nrow = 0, ncol = length(x))); names(df) <- x}
)
}
Bench <-
data_frame(ncol = 1:500) %>%
mutate(result = lapply(ncol, bench_fun))
X <- Bench %>%
mutate(result = lapply(result, as.data.frame)) %>%
unnest(result) %>%
group_by(ncol, expr) %>%
summarise(median = median(time, na.rm = TRUE)) %>%
ungroup()
ggplot(data = X,
mapping = aes(x = ncol,
y = median,
colour = expr)) +
geom_line()
```

I just love your thoroughness and the fact you go all out on something like this

Sometimes coding is just fun for the sillyness of it... keep doing that! Although I must say I like the benchmarking you did. It's often overlooked how efficiency is an integral part of good coding practices.

PJ

You are crazy man. Anyway good effort, impressed

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.