Utwórz puste dane.ramka
Próbuję zainicjować dane.Ramka bez rzędów. Zasadniczo chcę określić typy danych dla każdej kolumny i nazwać je, ale nie mam żadnych wierszy utworzonych w wyniku.
Najlepsze co do tej pory udało mi się zrobić to coś w stylu:
df <- data.frame(Date=as.Date("01/01/2000", format="%m/%d/%Y"),
File="", User="", stringsAsFactors=FALSE)
df <- df[-1,]
, który tworzy dane.ramka z jednym wierszem zawierającym wszystkie typy danych i nazwy kolumn, które chciałem, ale także tworzy bezużyteczny wiersz, który następnie musi zostać usunięty.
Czy jest na to lepszy sposób?13 answers
Po prostu zainicjalizuj go pustymi wektorami:
df <- data.frame(Date=as.Date(character()),
File=character(),
User=character(),
stringsAsFactors=FALSE)
Oto inny przykład z różnymi typami kolumn:
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
Uwaga:
Inicjalizacja data.frame
pustą kolumną niewłaściwego typu nie uniemożliwia dalszego dodawania wierszy o kolumnach różnych typów.
Ta metoda jest tylko trochę bezpieczniejsza w tym sensie, że będziesz miał prawidłowe typy kolumn od początku, stąd Jeśli Twój kod opiera się na sprawdzaniu typu kolumn, będzie praca nawet z data.frame
z zerowymi rzędami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-11 17:49:03
Jeśli masz już istniejącą ramkę danych, powiedzmy df
, która ma żądane kolumny, możesz po prostu utworzyć pustą ramkę danych, usuwając wszystkie wiersze:
empty_df = df[FALSE,]
Zauważ, że df
nadal zawiera dane, ale empty_df
NIE.
Znalazłem to pytanie szukając sposobu tworzenia nowej instancji z pustymi wierszami, więc myślę, że może to być pomocne dla niektórych osób.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 01:42:53
Możesz to zrobić bez podawania typów kolumn
df = data.frame(matrix(vector(), 0, 3,
dimnames=list(c(), c("Date", "File", "User"))),
stringsAsFactors=F)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-10 12:03:05
Możesz użyć read.table
z pustym łańcuchem wejściowym text
w następujący sposób:
colClasses = c("Date", "character", "character")
col.names = c("Date", "File", "User")
df <- read.table(text = "",
colClasses = colClasses,
col.names = col.names)
Alternatywnie określając col.names
jako ciąg znaków:
df <- read.csv(text="Date,File,User", colClasses = colClasses)
Podziękowania dla Richarda Scrivena za poprawę
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-28 21:22:59
Najbardziej efektywnym sposobem na to jest użycie structure
do utworzenia listy, która ma klasę "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)
Aby ująć to w perspektywie w porównaniu z obecnie akceptowaną odpowiedzią, Oto prosty benchmark:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 20:15:02
Jeśli szukasz krótkowzroczności:
read.csv(text="col1,col2")
Więc nie musisz określać nazw kolumn oddzielnie. Domyślny typ kolumny jest logiczny, dopóki nie wypełnisz ramki danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-19 08:48:25
Utworzyłem pustą ramkę danych używając następującego kodu
df = data.frame(id = numeric(0), jobs = numeric(0));
I próbował powiązać niektóre wiersze, aby wypełnić to samo w następujący sposób.
newrow = c(3, 4)
df <- rbind(df, newrow)
Ale zaczęło podawać niepoprawne nazwy kolumn w następujący sposób
X3 X4
1 3 4
Rozwiązaniem jest konwersja newrow do typu df w następujący sposób
newrow = data.frame(id=3, jobs=4)
df <- rbind(df, newrow)
Teraz wyświetla poprawną ramkę danych z nazwami kolumn w następujący sposób
id nobs
1 3 4
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-18 07:17:41
Just declare
table = data.frame()
Gdy spróbujesz rbind
w pierwszej linii utworzy ona Kolumny
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 15:42:49
Jeśli chcesz utworzyć puste dane.ramka z dynamicznymi nazwami (nazwy colnames w zmiennej) może pomóc:
names <- c("v","u","w")
df <- data.frame()
for (k in names) df[[k]]<-as.numeric()
Możesz również zmienić typy, jeśli potrzebujesz. like:
names <- c("u", "v")
df <- data.frame()
df[[names[1]]] <- as.numeric()
df[[names[2]]] <- as.character()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 16:34:22
Jeśli chcesz zadeklarować taką data.frame
z wieloma kolumnami, prawdopodobnie będzie trudno ręcznie wpisać wszystkie klasy kolumn. Szczególnie jeśli można skorzystać z rep
, takie podejście jest łatwe i szybkie (około 15% szybciej niż inne rozwiązanie, które można uogólnić w ten sposób):
Jeśli pożądane klasy kolumn znajdują się w wektorze colClasses
, możesz wykonać następujące czynności:
library(data.table)
setnames(setDF(lapply(colClasses, function(x) eval(call(x)))), col.names)
lapply
spowoduje powstanie listy żądanej długości, której każdy element jest po prostu pustym wektorem jak numeric()
lub integer()
.
setDF
konwertuje to list
przez odniesienie do data.frame
.
setnames
dodaje żądane nazwy według odniesienia.
Porównanie prędkości:
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
Jest również szybszy niż użycie structure
w podobny sposób:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 01:51:25
Jeśli nie masz nic przeciwko jawnemu określaniu typów danych, możesz to zrobić w ten sposób:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 17:25:37
Do Utwórz pustą ramkę danych , przekaż liczbę wierszy i kolumn potrzebnych do następującej funkcji:
create_empty_table <- function(num_rows, num_cols) {
frame <- data.frame(matrix(NA, nrow = num_rows, ncol = num_cols))
return(frame)
}
Aby utworzyć pustą ramkę podczas określania klasy każdej kolumny , wystarczy przekazać wektor pożądanych typów danych do następującej funkcji:
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)
}
Stosować w następujący sposób:
df <- create_empty_table(3, 3, c('character','logical','numeric'))
Co daje:
X1 X2 X3
1 <NA> NA NA
2 <NA> NA NA
3 <NA> NA NA
Aby potwierdzić swoje wybory, wykonaj następujące czynności:
lapply(df, class)
#output
$X1
[1] "character"
$X2
[1] "logical"
$X3
[1] "numeric"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 19:50:51
Powiedzmy, że nazwy kolumn są dynamiczne, możesz utworzyć pustą macierz o nazwie wiersz i przekształcić ją w ramkę danych.
nms <- sample(LETTERS,sample(1:10))
as.data.frame(t(matrix(nrow=length(nms),ncol=0,dimnames=list(nms))))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 04:37:41