2014-09-04 21 views
6

ayarlanmış bir dengesiz panel veri dengelemek için zarif bir yolu var dengelemek için zarif bir yolu? Ben (yani bazı bireylerin bazı verileri eksik) dengesiz panel ile başlayacak ve dengeli panelin (yani tüm bireylerin hiçbir veri eksik) ile bitirmek istiyorum. Aşağıda bazı örnek kod bulunmaktadır. Doğru sonuç kalması 'Frank' ve 'Edward' tüm gözlemler için ve o bazı eksik verileri sahip olduğu için 'Tony' kaldırılacak tüm gözlemler içindir. Teşekkür ederim. Bir paneli dengelemek içinR dengesiz panel veri

unbal <- data.frame(PERSON=c(rep('Frank',5),rep('Tony',5),rep('Edward',5)), YEAR=c(2001,2002,2003,2004,2005,2001,2002,2003,2004,2005,2001,2002,2003,2004,2005), Y=c(21,22,23,24,25,5,6,NA,7,8,31,32,33,34,35), X=c(1:15)) 
unbal 

cevap

5

bir yolu eksik verilerle bireyleri kaldırmaktır, başka bir yol, bir değer kayıp gözlemler için gibi NA veya 0 doldurmaktır. İlk yaklaşım için, onlara hiçbir NA olan satırları bulmak için complete.cases kullanabilirsiniz. Ardından en az bir eksik olan PERSON'u bulabilirsiniz.

missing.at.least.one <- unique(unbal$PERSON[!complete.cases(unbal)]) 
unbal[!(unbal$PERSON %in% missing.at.least.one),] 
# PERSON YEAR Y X 
# 1 Frank 2001 21 1 
# 2 Frank 2002 22 2 
# 3 Frank 2003 23 3 
# 4 Frank 2004 24 4 
# 5 Frank 2005 25 5 
# 11 Edward 2001 31 11 
# 12 Edward 2002 32 12 
# 13 Edward 2003 33 13 
# 14 Edward 2004 34 14 
# 15 Edward 2005 35 15 
+2

(UA doldurarak dengeli dengesiz paneli), bir işlev kullanabilirsiniz yapmak 'yapmak "plm" den paketlenmiş. (https://r-forge.r-project.org/R/?group_id=406 adresinden gerekli olan en son geliştirme sürümü) – Helix123

+0

Şimdi plm resmi CRAN sürümü (1.6-4) var. make.pbalanced 'dahil edildi (ve argüman' balance.type = c ("fill", "shared") 'biri verileri genişletip genişletmeyeceğinizi ya da azaltmayı seçebilir. – Helix123

3

Yani ben o "zarif" şartını karşılayan emin değilim, ama burada dengeli veri almak için kullanabileceğiniz genel amaçlı bir fonksiyon.

balanced<-function(data, ID, TIME, VARS, required=c("all","shared")) { 
    if(is.character(ID)) { 
     ID <- match(ID, names(data)) 
    } 
    if(is.character(TIME)) { 
     TIME <- match(TIME, names(data)) 
    } 
    if(missing(VARS)) { 
     VARS <- setdiff(1:ncol(data), c(ID,TIME)) 
    } else if (is.character(VARS)) { 
     VARS <- match(VARS, names(data)) 
    } 
    required <- match.arg(required) 
    idf <- do.call(interaction, c(data[, ID, drop=FALSE], drop=TRUE)) 
    timef <- do.call(interaction, c(data[, TIME, drop=FALSE], drop=TRUE)) 
    complete <- complete.cases(data[, VARS]) 
    tbl <- table(idf[complete], timef[complete]) 
    if (required=="all") { 
     keep <- which(rowSums(tbl==1)==ncol(tbl)) 
     idx <- as.numeric(idf) %in% keep 
    } else if (required=="shared") { 
     keep <- which(colSums(tbl==1)==nrow(tbl)) 
     idx <- as.numeric(timef) %in% keep 
    } 
    data[idx, ] 
} 

İlk parametre subsetine isteyen data.frame olan

balanced(unbal, "PERSON","YEAR") 

# PERSON YEAR Y X 
# 1 Frank 2001 21 1 
# 2 Frank 2002 22 2 
# 3 Frank 2003 23 3 
# 4 Frank 2004 24 4 
# 5 Frank 2005 25 5 
# 11 Edward 2001 31 11 
# 12 Edward 2002 32 12 
# 13 Edward 2003 33 13 
# 14 Edward 2004 34 14 
# 15 Edward 2005 35 15 

ile istediğiniz sonucu alabilirsiniz. İkinci parametre (ID=), veri kümesindeki her bir "kişiyi" tanımlayan sütun adlarının bir karakter vektörüdür. Daha sonra TIME= parametresi, her bir ID için farklı gözlem sürelerini belirten bir karakter vektörüdür. Son olarak, isteğe bağlı olarak (kimlik veya ZAMAN değerlerinden daha tüm diğer varsayılan) NA olması gereken alanların belirtmek için bir VARS= argüman belirtebilirsiniz. Son olarak, her kimlik her TIME için bir gözlem (varsayılan) olması gerekir olmadığını belirten required adlı son bir parametre yoktur ya da "ortak" olarak ayarlarsanız, yalnızca tüm kimlikleri için eksik olmayan değerlere sahip olduğunu TIMES dönecektir.

Yani örneğin

balanced(unbal, "PERSON","YEAR", "X") 

# PERSON YEAR Y X 
# 1 Frank 2001 21 1 
# 2 Frank 2002 22 2 
# 3 Frank 2003 23 3 
# 4 Frank 2004 24 4 
# 5 Frank 2005 25 5 
# 6 Tony 2001 5 6 
# 7 Tony 2002 6 7 
# 8 Tony 2003 NA 8 
# 9 Tony 2004 7 9 
# 10 Tony 2005 8 10 
# 11 Edward 2001 31 11 
# 12 Edward 2002 32 12 
# 13 Edward 2003 33 13 
# 14 Edward 2004 34 14 
# 15 Edward 2005 35 15 

Sadece "X" Tüm KİŞİ/YIL NA olmasını gerektirir ve bu tüm kayıtlar için geçerlidir, çünkü hiçbir alt ayar gerçekleşir. Sonra

balanced(unbal, "PERSON","YEAR", required="shared") 

# PERSON YEAR Y X 
# 1 Frank 2001 21 1 
# 2 Frank 2002 22 2 
# 4 Frank 2004 24 4 
# 5 Frank 2005 25 5 
# 6 Tony 2001 5 6 
# 7 Tony 2002 6 7 
# 9 Tony 2004 7 9 
# 10 Tony 2005 8 10 
# 11 Edward 2001 31 11 
# 12 Edward 2002 32 12 
# 14 Edward 2004 34 14 
# 15 Edward 2005 35 15 

yaparsanız hepsi bu yıllar için veri beri

TÜM kişiler için yıllar 2001, 2002, 2004, 2005 için veri olsun.

Şimdi

kullanımı biraz daha farklı bir örnek verileri oluşturmasına izin Edward Bu

balanced(unbal2, "PERSON","YEAR") 
# [1] PERSON YEAR Y  X  
# <0 rows> (or 0-length row.names) 

şimdi başka bir şey döndüren demektir 2006 için bir değere sahip tek kişi olduğunu

unbal2 <- unbal 
unbal2[15, 2] <- 2006 
tail(unbal2) 

# PERSON YEAR Y X 
# 10 Tony 2005 8 10 
# 11 Edward 2001 31 11 
# 12 Edward 2002 32 12 
# 13 Edward 2003 33 13 
# 14 Edward 2004 34 14 
# 15 Edward 2006 35 15 

Bildirim şimdi set Tüm kişilerin veri sahibi olmaları nedeniyle, 2001, 2004, 2004 için verileri döndürecektir. o yıllar.

+0

Çok hoş. Bunu okuyana kadar "dengeli" ile ne anlama geldiğini anlamamayı itiraf ediyorum. Bu çok daha güzel bir genel çözümdür. – nograpes

+0

Bu yöntemi denedim ve çok yavaş olduğunu söyleyebilirim – Mislav

1

Kullandığım çözüm budur - data.table paketinin kullanışlı özelliklerini (güzel birleştirme yetenekleri dahil) kullanır ve verilerinizin zaten bir data.table nesnesi olduğunu varsayar. Bu nispeten basit ve umarım takip etmek kolaydır. Her birey için "bireyler" ve "zaman periyotları" nın her bir kombinasyonu için girişlerle dengeli bir panel döndürür - yani, her zaman için her birey için bir gözlem olan bir panel.

library(data.table) 
Balance_Panel = function(Data, Indiv_ColName, Time_ColName){ 
    Individuals = unique(Data[, get(Indiv_ColName)]) 
    Times = unique(Data[, get(Time_ColName)]) 

    Full_Panel = data.table(expand.grid(Individuals, Times)) 
    setnames(Full_Panel, c(Indiv_ColName, Time_ColName)) 
    setkeyv(Full_Panel, c(Indiv_ColName, Time_ColName)) 
    setkeyv(Data, c(Indiv_ColName, Time_ColName)) 
    return(Data[Full_Panel]) 
} 

Örnek Kullanım:

Balanced_Data = Balance_Panel(Data, "SubjectID", "ObservationTime") 
2

ben kullandım bir çözüm geçici satırlar olarak kolon ve birimler olarak yıllık geniş biçime veri çerçevesini yeniden şekillendirmek ve ardından sıra komple durumlar için kontrol etmektir . Tek bir değişkene sahipseniz - eğer eksikse - tüm gözlemin eksik olduğu anlamına gelirse, bunu yapmanız en kolay yoldur.

library(data.table) 
library(reshape2) 

Birincisi, adildir (ASiMETRi) ana veri çerçevesinin bir alt kümesini, kimlik değişkeni ("ADI"), zaman değişkeni almak ("YIL":

aşağıdaki kütüphaneleri kullanmak) ve bir değişken değişken ("X" veya "Y").

df<- unbal[c("NAME", "YEAR", "X")] 

İkincisi, geniş formatlı yapmak için yeni veri çerçevesini yeniden şekillendirmek. Bu, her "NAME" nin tek bir satır olduğu ve her yıl için "X" in bir sütun olduğu bir veri çerçevesi oluşturur.

df <- dcast(df, NAME ~ YEAR, value.var = "X") 

Üçüncüsü, her satır için complete.cases'i çalıştırın. Eksik verilere sahip tüm NAME tamamen kaldırılacak.

df <- df[complete.cases(df),] 

Dördüncüsü, geri uzun biçime veri çerçevesini yeniden şekillendirmek (eğer daha önce ne vardı geri isimlerini değiştirmek isteyebilirsiniz böylece varsayılan olarak, bu, jenerik adları değişkenleri verir).

df <- melt(df, id.vars = "ID") 
setnames(df, "variable", "YEAR") 

NOT: YEAR, yaklaşımı kullanarak varsayılan olarak bir faktör değişkeni olur. YEAR değişkeniniz sayısalsa, değişkeni buna göre değiştirmek isteyeceksiniz. Örneğin:

test4$year <- as.character(test4$year) 
test4$year <- as.numeric(test4$year) 

Beşinci ve altıncı, oluşturduğunuz veri çerçeve içinde sadece "NAME" ve "YIL" değişkenleri almak ve ardından orijinal veri çerçevesi ile birleştirme (ve vakaları damla emin olun biri tersi ile alakalı ise, oluşturduğunuz d veri çerçevesi bulunmayan orijinal veri çerçevesi)

df <- df[c("NAME", "YEAR")] 
balanced <- merge.data.frame(df, unbal, by = c("NAME", "YEAR"), all.x = TRUE)