합치기 - r 빈 행렬 만들기




빈 data.frame 만들기 (10)

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

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

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

이는 원하는 모든 데이터 유형과 열 이름을 포함하는 단일 행을 갖는 data.frame을 작성하지만 쓸모없는 행을 작성하여 제거해야합니다.

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


그냥 빈 벡터로 그것을 초기화하십시오 :

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 

주의 :

잘못된 유형의 빈 열을 사용하여 data.frame 을 초기화한다고해서 다른 유형의 열이있는 행을 더 이상 추가 할 수 있습니다.
이 방법은 처음부터 올바른 열 유형을 사용한다는 점에서 조금 더 안전 합니다. 따라서 코드가 일부 열 유형 검사에 의존하면 0 행이있는 data.frame 에서도 작동합니다.


그냥 선언해라.

table = data.frame()

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


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

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 

다음과 같이 입력 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 를 문자열로 지정하는 col.names 도 있습니다.

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

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


동적 이름 (변수의 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()

많은 수의 열이있는 그런 data.frame 을 선언하고 싶다면 모든 열 클래스를 손으로 입력하는 것이 어려울 것입니다. 특히 rep 활용할 수 있다면이 방법은 쉽고 빠릅니다 (이와 같이 일반화 할 수있는 다른 솔루션보다 약 15 % 빠름).

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

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

lapply 는 원하는 길이의리스트를 lapply 할 것이고, 각 요소는 단순히 numeric() 이나 integer() 처럼 빈 타입의 벡터이다.

setDF 는이 listsetDF 을 참조하여 변환합니다.

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

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

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

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

> 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 행렬을 구속 할 때 결과는 여전히 행렬이므로 변수는 모두 data.frame으로 변환하기 전에 하나의 유형으로 강제 변환됩니다


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

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"

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

empty_df = df[FALSE,]

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

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







r-faq