创build一个空的data.frame

我试图初始化data.frame没有任何行。 基本上,我想为每个列指定数据types并命名它们,但是没有创build任何行作为结果。

到目前为止,我所能做到的最好的事情是:

df <- data.frame(Date=as.Date("01/01/2000", format="%m/%d/%Y"), File="", User="", stringsAsFactors=FALSE) df <- df[-1,] 

它创build了一个data.frame,其中包含了我想要的所有数据types和列名,但也创build了一个无用的行,然后需要删除。

有一个更好的方法吗?

只需用空向量初始化它:

 df <- data.frame(Date=as.Date(character()), File=character(), User=character(), stringsAsFactors=FALSE) 

以下是不同列types的其他示例:

 df <- data.frame(Doubles=double(), Ints=integer(), Factors=factor(), Logicals=logical(), Characters=character(), stringsAsFactors=FALSE) str(df) > str(df) 'data.frame': 0 obs. of 5 variables: $ Doubles : num $ Ints : int $ Factors : Factor w/ 0 levels: $ Logicals : logi $ Characters: chr 

注意:

使用错误types的空列初始化data.frame不会阻止进一步添加具有不同types列的行。
这个方法从一开始就拥有正确的列types,因此如果你的代码依赖于一些列types检查,它甚至可以在零data.frame工作。

您可以在不指定列types的情况下进行操作

 df = data.frame(matrix(vector(), 0, 3, dimnames=list(c(), c("Date", "File", "User"))), stringsAsFactors=F) 

如果你已经有了一个现存的数据框 ,比如说df有你想要的列,那么你可以通过删除所有的行来创build一个空的数据框:

 empty_df = df[FALSE,] 

注意df仍然包含数据,但是empty_df不包含数据。

我发现这个问题寻找如何创build一个空行的新实例,所以我认为这可能对某些人有帮助。

您可以使用read.table为空的string作为inputtext ,如下所示:

 colClasses = c("Date", "character", "character") col.names = c("Date", "File", "User") df <- read.table(text = "", colClasses = colClasses, col.names = col.names) 

或者将col.names指定为一个string:

 df <- read.csv(text="Date,File,User", colClasses = colClasses) 

感谢Richard Scriven的改进

最有效的方法是使用structure来创build一个包含"data.frame"类的列表:

 structure(list(Date = as.Date(character()), File = character(), User = character()), class = "data.frame") # [1] Date File User # <0 rows> (or 0-length row.names) 

与目前接受的答案相比,这是一个简单的基准:

 s <- function() structure(list(Date = as.Date(character()), File = character(), User = character()), class = "data.frame") d <- function() data.frame(Date = as.Date(character()), File = character(), User = character(), stringsAsFactors = FALSE) library("microbenchmark") microbenchmark(s(), d()) # Unit: microseconds # expr min lq mean median uq max neval # s() 58.503 66.5860 90.7682 82.1735 101.803 469.560 100 # d() 370.644 382.5755 523.3397 420.1025 604.654 1565.711 100 

如果你正在寻找简短:

 read.csv(text="col1,col2") 

所以你不需要单独指定列名。 在填充数据框之前,您将获得默认的列types逻辑。

我使用下面的代码创build了空的数据框

 df = data.frame(id = numeric(0), jobs = numeric(0)); 

并试图绑定一些行来填充相同的如下。

 newrow = c(3, 4) df <- rbind(df, newrow) 

但它开始提供不正确的列名如下

  X3 X4 1 3 4 

解决这个问题的方法是将newrow转换为dftypes,如下所示

 newrow = data.frame(id=3, jobs=4) df <- rbind(df, newrow) 

现在在显示列名时给出正确的数据框,如下所示

  id nobs 1 3 4 

只要声明table = data.frame()当你尝试rbind的第一行就会创build列

如果你想要声明这样一个有很多列的data.frame ,那么用手input所有的列类可能会很data.frame 。 特别是如果你可以使用rep ,这种方法简单快捷(比其他解决scheme的速度快15%左右):

如果您所需的列类位于向量colClasses ,则可以执行以下操作:

 library(data.table) setnames(setDF(lapply(colClasses, function(x) eval(call(x)))), col.names) 

lapply会生成一个所需长度的列表,其中的每个元素只是一个空的types向量,如numeric()integer()

setDF通过引用setDF转换这个list

setnames通过引用添加所需的名称。

速度比较:

 classes <- c("character", "numeric", "factor", "integer", "logical","raw", "complex") NN <- 300 colClasses <- sample(classes, NN, replace = TRUE) col.names <- paste0("V", 1:NN) setDF(lapply(colClasses, function(x) eval(call(x)))) library(microbenchmark) microbenchmark(times = 1000, read = read.table(text = "", colClasses = colClasses, col.names = col.names), DT = setnames(setDF(lapply(colClasses, function(x) eval(call(x)))), col.names)) # Unit: milliseconds # expr min lq mean median uq max neval cld # read 2.598226 2.707445 3.247340 2.747835 2.800134 22.46545 1000 b # DT 2.257448 2.357754 2.895453 2.401408 2.453778 17.20883 1000 a 

它也比以类似的方式使用structure更快:

 microbenchmark(times = 1000, DT = setnames(setDF(lapply(colClasses, function(x) eval(call(x)))), col.names), struct = eval(parse(text=paste0( "structure(list(", paste(paste0(col.names, "=", colClasses, "()"), collapse = ","), "), class = \"data.frame\")")))) #Unit: milliseconds # expr min lq mean median uq max neval cld # DT 2.068121 2.167180 2.821868 2.211214 2.268569 143.70901 1000 a # struct 2.613944 2.723053 3.177748 2.767746 2.831422 21.44862 1000 b 

如果你不介意不明确指定数据types,你可以这样做:

 headers<-c("Date","File","User") df <- as.data.frame(matrix(,ncol=3,nrow=0)) names(df)<-headers #then bind incoming data frame with col types to set data types df<-rbind(df, new_df) 

如果你想创build一个空的data.frame与dynamic名称(colnames在一个variables),这可以帮助:

 names <- c("v","u","w") df <- data.frame() for (k in names) df[[k]]<-as.numeric() 

如果你需要,你也可以改变types。 喜欢:

 names <- c("u", "v") df <- data.frame() df[[names[1]]] <- as.numeric() df[[names[2]]] <- as.character() 

创build一个空的数据框 ,请将所需的行数和列数传递给以下函数:

 create_empty_table <- function(num_rows, num_cols) { frame <- data.frame(matrix(NA, nrow = num_rows, ncol = num_cols)) return(frame) } 

在指定每列的类时创build一个空框架,只需将所需数据types的vector传递到以下函数中:

 create_empty_table <- function(num_rows, num_cols, type_vec) { frame <- data.frame(matrix(NA, nrow = num_rows, ncol = num_cols)) for(i in 1:ncol(frame)) { print(type_vec[i]) if(type_vec[i] == 'numeric') {frame[,i] <- as.numeric(df[,i])} if(type_vec[i] == 'character') {frame[,i] <- as.character(df[,i])} if(type_vec[i] == 'logical') {frame[,i] <- as.logical(df[,i])} if(type_vec[i] == 'factor') {frame[,i] <- as.factor(df[,i])} } return(frame) } 

使用方法如下:

 df <- create_empty_table(3, 3, c('character','logical','numeric')) 

这使:

  X1 X2 X3 1 <NA> NA NA 2 <NA> NA NA 3 <NA> NA NA 

要确认您的select,请运行以下命令:

 lapply(df, class) #output $X1 [1] "character" $X2 [1] "logical" $X3 [1] "numeric" 

假设你的列名是dynamic的,你可以创build一个空的行名matrix,并将其转换为数据框。

 nms <- sample(LETTERS,sample(1:10)) as.data.frame(t(matrix(nrow=length(nms),ncol=0,dimnames=list(nms))))