创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))))