it-swarm.dev

빈 data.frame 만들기

모든 행없이 data.frame을 초기화하려고합니다. 기본적으로 각 열의 데이터 형식을 지정하고 이름을 지정하려고하지만 그 결과로 생성 된 행은 없습니다.

지금까지 내가 할 수 있었던 최선은 다음과 같습니다.

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

어떤 데이터 형식과 원하는 열 이름을 모두 포함하는 단일 행을 가진 data.frame을 만들지 만 쓸모없는 행을 만들어서 제거해야합니다.

이 작업을 수행하는 더 좋은 방법이 있습니까?

413
Jeff Allen

빈 벡터로 초기화하십시오.

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

열 유형이 다른 다른 예는 다음과 같습니다.

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 

N.B. :

잘못된 유형의 빈 열로 data.frame을 (를) 초기화해도 다른 유형의 열이있는 행을 더 이상 추가 할 수 없습니다.
이 방법은 처음부터 올바른 열 유형을 가지므로 코드가 일부 열 유형 확인에 의존한다는 점에서 약간 safer 입니다. 행이 0 인 data.frame에서도 작동합니다.

587
digEmAll

이미 존재하는 데이터 프레임이 있다면 , df에 원하는 열이 있다고 가정하면 모든 행을 제거하여 빈 데이터 프레임을 만들 수 있습니다.

empty_df = df[FALSE,]

df에는 여전히 데이터가 있지만 empty_df에는 데이터가 들어 있지 않습니다.

이 질문은 빈 행을 사용하여 새 인스턴스를 만드는 방법을 찾는 것이므로 일부 사람들에게는 도움이 될 것이라고 생각합니다.

95
toto_tico

열 유형을 지정하지 않고도이 작업을 수행 할 수 있습니다.

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

다음과 같이 text 입력에 빈 문자열을 사용하여 read.table를 사용할 수 있습니다.

colClasses = c("Date", "character", "character")
col.names = c("Date", "File", "User")

df <- read.table(text = "",
                 colClasses = colClasses,
                 col.names = col.names)

문자열로 col.names를 지정하는 방법도 있습니다.

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

개선을 위해 Richard Scriven에게 감사드립니다.

48
Rentrop

가장 효율적인 방법은 structure을 사용하여 "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
21
Thomas

너가 부족을 찾고 있으면 :

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

따라서 별도로 열 이름을 지정할 필요가 없습니다. 데이터 프레임을 채울 때까지 기본 열 유형 논리를 가져옵니다.

16
marc

그냥 선언해라.

table = data.frame()

첫 번째 줄을 rbind하면 열이 만들어집니다.

14
Daniel Fischer

다음 코드를 사용하여 빈 데이터 프레임을 만들었습니다.

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

다음과 같이 일부 행을 바인드하여 동일하게 채 웁니다.

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

하지만 다음과 같이 잘못된 열 이름을 제공하기 시작했습니다.

  X3 X4
1  3  4

이 문제에 대한 해결책은 newrow를 다음과 같이 df 유형으로 변환하는 것입니다.

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

다음과 같이 열 이름과 함께 표시 될 때 올바른 데이터 프레임을 제공합니다.

  id nobs
1  3   4 
10
Shrikant Prabhu

데이터 유형을 명시 적으로 지정하지 않더라도 다음과 같이 할 수 있습니다.

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)
3
Odysseus Ithaca

동적 이름 (변수의 colnames)을 사용하여 빈 data.frame을 만들려면 다음을 수행하면 도움이됩니다.

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

필요한 경우 형식을 변경할 수 있습니다. 처럼:

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

빈 데이터 프레임 만들기에 필요한 행 수와 열 수를 다음 함수에 전달합니다.

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

빈 프레임 각 열의 클래스를 지정하는 동안을 만들려면 원하는 데이터 형식의 벡터를 다음 함수로 전달하기 만하면됩니다.

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

선택 사항을 확인하려면 다음을 실행하십시오.

lapply(df, class)

#output
$X1
[1] "character"

$X2
[1] "logical"

$X3
[1] "numeric"
2
Cybernetic

많은 컬럼을 가진 그런 data.frame를 선언하고 싶다면 모든 컬럼 클래스를 손으로 직접 입력하는 것이 어려울 것입니다. 특히 rep을 사용할 수있는 경우이 방법은 쉽고 빠릅니다 (이렇게 일반화 할 수있는 다른 솔루션보다 약 15 % 빠름).

원하는 열 클래스가 벡터 colClasses에 있으면 다음을 수행 할 수 있습니다.

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

lapplynumeric() 또는 integer()과 같이 빈 형식의 벡터 인 각 요소의 원하는 길이 목록을 생성합니다.

setDFdata.frame를 참조하여이 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
2
MichaelChirico

데이터 프레임에서 메타 데이터 (열 이름 및 유형) 추출 (예 : 버그를 제어하고 있음 ) :

colums_and_types <- sapply(df, class)

# prints: "c('col1', 'col2')"
print(dput(as.character(names(colums_and_types))))

# prints: "c('integer', 'factor')"
dput(as.character(as.vector(colums_and_types)))

그런 다음 read.table를 사용하여 빈 데이터 프레임을 만듭니다.

read.table(text = "",
   colClasses = c('integer', 'factor'),
   col.names = c('col1', 'col2'))
0
toto_tico

열 이름이 동적 인 경우 빈 행 이름의 행렬을 만들어 데이터 프레임으로 변환 할 수 있습니다.

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

data.table를 사용하여 각 열에 대해 데이터 유형을 지정할 수 있습니다.

library(data.table)    
data=data.table(a=numeric(), b=numeric(), c=numeric())
0
Rushabh

이 질문은 구체적으로 내 관심 사항을 설명하지는 않았지만 (매개 변수화 된 개수의 열과 강요없이이 작업을 수행하려는 경우에 대비하여 여기 개요)

> require(dplyr)
> dbNames <- c('a','b','c','d')
> emptyTableOut <- 
    data.frame(
        character(), 
        matrix(integer(), ncol = 3, nrow = 0), stringsAsFactors = FALSE
    ) %>% 
    setNames(nm = c(dbNames))
> glimpse(emptyTableOut)
Observations: 0
Variables: 4
$ a <chr> 
$ b <int> 
$ c <int> 
$ d <int>

연결된 질문에 대한 divibisan 상태로,

... 행렬이 하나의 데이터 유형 만 가질 수 있다는 이유는 [열거 형과 그 구성 요소 유형을 묶을 때] [강제 변환]이 발생하기 때문입니다. 2 행렬을 cbind하면 그 결과는 여전히 행렬이므로 data.frame으로 변환하기 전에 변수가 모두 단일 유형으로 강제 변환됩니다

0
d8aninja