2010-08-09 39 views
28

我很驚訝地看到R在連接向量時會將因素強制爲一個數字。即使級別相同,也會發生這種情況。例如:如何連接因子,而不將它們轉換爲整數級別?

> facs <- as.factor(c("i", "want", "to", "be", "a", "factor", "not", "an", "integer")) 
> facs 
[1] i  want to  be  a  factor not  an  integer 
Levels: a an be factor i integer not to want 
> c(facs[1 : 3], facs[4 : 5]) 
[1] 5 9 8 3 1 

什麼是R(在我的情況下,這些向量可能會相當大)的地道方式?謝謝。

回答

27

R Mailing list

unlist(list(facs[1 : 3], facs[4 : 5])) 

要 'cbind' 因素,做

data.frame(facs[1 : 3], facs[4 : 5]) 
6

哇,我從來沒有意識到它做到了。這裏是一個變通:

x <- c(facs[1 : 3], facs[4 : 5]) 
x <- factor(x, levels=1:nlevels(facs), labels=levels(facs)) 
x 

隨着輸出:

[1] i want to be a 
Levels: a an be factor i integer not to want 

如果兩個矢量具有相同的水平在這裏它纔有效。

+0

十分感謝!我剛纔發現,如果你事先不知道fac是一個因素類型,那麼unlist(list(facs [1:3],facs [4:5]))也可以工作。 – Keith 2010-08-09 20:18:08

+0

以這種方式手動設置等級不適用於我的特殊問題。 (我有0級的水平,我可以減去1然後重新構造這個因子,但是,這是脆弱的,在scrutabality spectrum的較低端,即使是R.)相反(hooray?)我用'unlist列表(...))'。 – 2013-04-01 04:50:18

8

另一種解決方法是將該因子轉換爲字符向量,然後在您精簡連接時轉換回來。

cfacs <- as.character(facs) 
x <- c(cfacs[1:3], cfacs[4:5]) 

# Now choose between 
factor(x) 
# and 
factor(x, levels = levels(facs)) 
4

這是一個非常糟糕 - [R疑難雜症。沿着這條線,這是一個吞噬了我幾個小時的時間。

x <- factor(c("Yes","Yes","No", "No", "Yes", "No")) 
y <- c("Yes", x) 

> y 
[1] "Yes" "2" "2" "1" "1" "2" "1" 
> is.factor(y) 
[1] FALSE 

在我看來,更好的解決辦法是裏奇的,強制性的。

> y <- c("Yes", as.character(x)) 
> y 
[1] "Yes" "Yes" "Yes" "No" "No" "Yes" "No" 
> y <- as.factor(y) 
> y 
[1] Yes Yes Yes No No Yes No 
Levels: No Yes 

只要你得到正確設置的水平,就像Richie提到的那樣。

0

基於其在轉換爲字符我使用下面的函數來連接因素,其他答案:

concat.factor <- function(...){ 
    as.factor(do.call(c, lapply(list(...), as.character))) 
} 

你可以使用這個功能就像您使用c

0

這裏是另一種方式來增加的一個因素變量時設置稍有不同:

facs <- factor(1:3, levels=1:9, 
       labels=c("i", "want", "to", "be", "a", "factor", "not", "an", "integer")) 
facs 
# [1] i  want to  be  a  factor not  an  integer 
# Levels: a an be factor i integer not to want 
facs[4:6] <- levels(facs)[4:6] 
facs 
# [1] i  want to  be  a  factor 
# Levels: i want to be a factor not an integer 
0

出於這個原因,我更喜歡用的因素在裏面工作data.frames:

df <- data.frame(facs = as.factor(
     c("i", "want", "to", "be", "a", "factor", "not", "an", "integer"))) 

和子集它使用subset()或dplyr :: filter()等而不是行索引。因爲我沒有有意義的子集標準在這種情況下,我只是用頭()和尾部():

df1 <- head(df, 4) 
df2 <- tail(df, 2) 

然後你就可以很容易地操縱它們,例如:

dfc <- rbind(df1, df2) 
dfc$facs 
#[1] i  want to  be  an  integer 
#Levels: a an be factor i integer not to want