2014-02-28 41 views
9

當使用兩個data.framesrbindNA值時,我強制使用可變類型R的方式有問題。我說明的例子:爲什麼R在將NA值預先賦予具有因子的數據幀時更改變量類型?

x<-factor(sample(1:3,10,T)) 
y<-rnorm(10) 
dat<-data.frame(x,y) 
NAs<-data.frame(matrix(NA,ncol=ncol(dat),nrow=nrow(dat))) 
colnames(NAs)<-colnames(dat) 

現在的目標是追加datNAs,同時保持變量類型factorxynumeric。當我給:

dat_forward<-rbind(dat,NAs) 
is.factor(dat_forward$x) 

這工作正常。然而,使用rbind向後方向失敗:

dat_backward<-rbind(NAs,dat) 
is.factor(dat_backward$x) 
is.character(dat_backward$x) 

現在x被強制轉換爲字符的水平。我很困惑 - 即使我使用其他綁定順序,它也不能保持因子類型嗎?爲了實現我的目標,我的代碼會發生什麼直接變化?

+3

從'rbind.data.frame':「那麼它需要的列的類都是從第一個數據幀。 ..「。這就是爲什麼你在調用'rbind'時看到訂單問題。 – josliber

+0

@josilber謝謝,有沒有一個簡單的解決我的問題? – tomka

+4

將「NAs」的第一列轉換爲因子? –

回答

9

下面是一個相當簡單的方法來獲得正確的列類別:

x <- rbind(dat[1,], NAs, dat)[-1,] 
str(x) 
# $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... 
# $ y: num NA NA NA NA NA NA NA NA NA NA ... 

更一般地,如果你真的需要這通常,你可以創建一個rbind樣函數,它指示其列班你想強迫所有的data.frame一個額外的參數其他列:

myrbind <- function(x, ..., template=x) { 
    do.call(rbind, c(list(template[1,]), list(x), list(...)))[-1,] 
} 

str(myrbind(NAs, dat, template=dat)) 
# 'data.frame': 20 obs. of 2 variables: 
# $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... 
# $ y: num NA NA NA NA NA NA NA NA NA NA ... 

## If no 'template' argument is supplied, myrbind acts just like rbind  
str(myrbind(dat, NAs)) 
# 'data.frame': 20 obs. of 2 variables: 
# $ x: Factor w/ 3 levels "1","2","3": 3 3 3 3 2 3 1 1 3 2 ... 
# $ y: num 0.303 1.77 -1.38 1.731 0.033 ... 
+0

謝謝,這是一個簡單的解決方案和一個不錯的功能。 – tomka

2

?rbind.data.frame,我們讀到:「然後它從第一個數據幀中取出列的類......」。這就是您撥打rbind時看到訂單問題的原因。

要使用的dat_backward排序得到的變量類的dat_forward,你可以只構建dat_forward和重新排序列:

dat_new = rbind(dat, NAs)[c((nrow(dat)+1):(nrow(dat)+nrow(NAs)), 1:nrow(dat)),] 
str(dat_new) 
# 'data.frame': 20 obs. of 2 variables: 
# $ x: Factor w/ 3 levels "1","2","3": NA NA NA NA NA NA NA NA NA NA ... 
# $ y: num NA NA NA NA NA NA NA NA NA NA ... 
3

同樣,你可以只轉換列NAsfactor

NAs$x<-factor(NAs$x) 
dat_backward<-rbind(NAs,dat) 
is.factor(dat_backward$x) # TRUE 
is.character(dat_backward$x) # FALSE 
0

一種方法是使用正確的列數據類型創建NAs。這可以與

num.rows <- 30 
NAs <- dat[NA,][1:num.rows,] 
3

data.frame需要,可以輕鬆地與

NAs <- dat[NA,] 

您也可以讓儘可能多的行做做了很多的事情不正確時rbind「荷蘭國際集團不同類型的合作,並且涉及特別是當因素。開始使用data.table(1.8.11+)來代替,你不會有這些問題:

library(data.table) 
dt1 = data.table(dat) 
dt2 = data.table(NAs) 

sapply(rbind(dt1, dt2), class) 
#  x   y 
# "factor" "numeric" 
sapply(rbind(dt2, dt1), class) 
#  x   y 
# "factor" "numeric" 
相關問題