0

How i can create empty dataframe with column name where column is a vector any length

c("A","B","C")

Im try

df<-data.frame()
colnames(df)<-c("A","B")

But is not working

Nikolay
  • 131
  • 1
  • 7
  • 4
    Why do you need an empty data.frame? You can do this: `df <- data.frame(A = numeric(n), B = character(n), C = logical(n))` for any `n`. – Roland Oct 21 '15 at 09:03
  • `data.frame(A = c(), B = c())` – Ronak Shah Oct 21 '15 at 09:03
  • 4
    @RonakShah Have you checked the output? – akrun Oct 21 '15 at 09:03
  • As @Roland said, you will virtually never need to do something similar. – nicola Oct 21 '15 at 09:04
  • @nicola I have actually used this in production code. It's not the most efficient strategy to fill a data.frame in a loop, but the code is easy to read and understand. – Roland Oct 21 '15 at 09:06
  • @akrun yes, it gives data frame with 0 columns and 0 rows – Ronak Shah Oct 21 '15 at 09:06
  • 1
    But, it also doesn't show any names, i.e. the OP wanted to have A, B in the output as columns, here you have 0 variables and 0 observations. `str(data.frame(A = c(), B = c())) 'data.frame': 0 obs. of 0 variables` – akrun Oct 21 '15 at 09:07
  • @Roland I think that this kind of practices must be discouraged as much as possible... One reason why people say "R is slow" it's because codes are full of loop with `rbind(new,oldDF)`, which is basically the less efficient thing you can do in R (and, as far as I'm concerned not so much readable either). Of course, everyone of us used something similar in any environment I guess... – nicola Oct 21 '15 at 09:10
  • @nicola I never said I grow anything in a loop. Pre-allocate and fill. – Roland Oct 21 '15 at 09:12
  • @Roland Ah ok, maybe a misunderstanding. My "never need" was referring to create an empty `data.frame`. If preallocated is perfectly fine. – nicola Oct 21 '15 at 09:14

2 Answers2

11
x <- LETTERS[1:3]
df <- as.data.frame(matrix(,0,length(x)))
names(df) <- x

str(df)
# 'data.frame': 0 obs. of  3 variables:
#  $ A: logi 
#  $ B: logi 
#  $ C: logi 

With OP's vector:

x <- c("field1","field2", "field3")
df <- as.data.frame(matrix(,0,length(x)))
names(df) <- x
str(df)
# 'data.frame': 0 obs. of  3 variables:
#  $ field1: logi 
#  $ field2: logi 
#  $ field3: logi 
  • For example im have vector c("field1","field2, filed3") – Nikolay Oct 21 '15 at 09:09
  • With a line: `as.data.frame(matrix(nrow=0,ncol=length(x),dimnames=list(NULL,x)))` – nicola Oct 21 '15 at 09:12
  • @nicola feel free to edit. –  Oct 21 '15 at 09:12
  • A comment is more than enough. I upvoted your answer, but I felt almost guilty, because I hate this practice in R (allocating empty objects and then let them grow) :) – nicola Oct 21 '15 at 09:16
  • @nicola Yes, I understand this. I personally don't proceed this way. –  Oct 21 '15 at 09:17
  • 1
    I believe that there are cases where this can be useful. Imagine for example the case where you want to generate a table (dataframe) where each row is the result of calculations performed on temporary data retrieved from an external source. In such a situation you may not know at the beginning the number of rows that your resulting data frame will have. I think that `rbind`ing each row, starting with an empty dataframe with named columns, would make sense there. – RHertel Oct 21 '15 at 09:25
  • 1
    @RHertel No, guess a reasonable size, (over-)allocate that, grow in chunks only if needed, subset to the final size in the end. – Roland Oct 21 '15 at 09:30
  • 1
    @RHertel If you know the number of iterations (as one usually does), you allocate a `list` before in which you put the `data.frame` returned from the external source. At the end of the loop, you `rbind` them all together with `do.call`. Or do like Roland suggested. – nicola Oct 21 '15 at 09:34
6

You can try this:

df1 <- data.frame(matrix(vector(),ncol=3))
colnames(df1) <-c("A","B","C")
df1
#[1] A B C
#<0 rows> (or 0-length row.names)
David Arenburg
  • 91,361
  • 17
  • 137
  • 196
RHertel
  • 23,412
  • 5
  • 38
  • 64