2014-12-23 165 views
5

我很抱歉,如果有一個答案已經存在這個......我看了卻找不到一個。將因子水平轉換爲數字

我試圖將一個矩陣的因子轉換成一個矩陣的數字,對應於每個列的因子值。很簡單,對吧?然而,當我嘗試這樣做時,我遇到了各種各樣非常奇怪的問題。

讓我解釋一下。下面是一個示例數據集:

demodata2 <- matrix(c("A","B","B","C",NA,"A","B","B",NA,"C","A","B",NA,"B",NA,"C","A","B",NA,NA,NA,"B","C","A","B","B",NA,"B","B",NA,"B","B",NA,"C","A",NA), nrow=6, ncol=6) 
democolnames <- c("Q","R","S","T","U","W") 
colnames(demodata2) <- democolnames 

產量:

 Q R S T U W 
[1,] "A" "B" NA NA "B" "B" 
[2,] "B" "B" "B" NA "B" "B" 
[3,] "B" NA NA NA NA NA 
[4,] "C" "C" "C" "B" "B" "C" 
[5,] NA "A" "A" "C" "B" "A" 
[6,] "A" "B" "B" "A" NA NA 

確定。所以我想是這樣的:

 Q R S T U W 
1 1 2 <NA> <NA> 1 2 
2 2 2 2 <NA> 1 2 
3 2 <NA> <NA> <NA> <NA> <NA> 
4 3 3 3 2 1 3 
5 <NA> 1 1 3 1 1 
6 1 2 2 1 <NA> <NA> 

沒問題。試試吧as.numeric(demodata2)

> as.numeric(demodata2) 
[1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 
[30] NA NA NA NA NA NA NA 
Warning message: 
NAs introduced by coercion 

不滿意。讓我們嘗試只有一列...

> as.numeric(demodata2[,3]) 
[1] NA NA NA NA NA NA 
Warning message: 
NAs introduced by coercion 

*編輯*

這些實際上應該是因素,而不是字符(感謝@Carl Witthoft和@smci)......因此,讓這成數據幀...

> demodata2 <- as.data.frame(demodata2) 
> as.numeric(demodata2) 
Error: (list) object cannot be coerced to type 'double' 

沒有。 但等待......這裏是它有趣......

> as.numeric(demodata2$S) 
[1] NA 2 NA 3 1 2 

嗯,這是正確的。讓我們來驗證我可以按編號做主叫列:

> as.numeric(demodata2[,3]) 
[1] NA 2 NA 3 1 2 

確定。所以我可以通過迭代ncol次來按列組裝我的新矩陣來做這個列......但是有沒有更好的方法?

爲什麼它會以矩陣的形式出現,而不是數據幀呢? < - 編輯實際上,這現在是非常明顯的...在矩陣形式,這些是字符,而不是因素。我的錯。問題仍然是關於數據幀,但...

謝謝! (並指向我現有的答案是完全沒問題)

+4

你舉的例子是** **不是因素。小心你的命名。 –

+1

你的例子是一個字符串矩陣,而不是因素。字符串沒有任何因子水平等。 – smci

+0

我的歉意。這個問題從導入的數據集開始,其中字符串被自動假定爲因素(除非另有指定)。當我嘗試重新創建它用於stackoverflow使用時發生錯誤。 – rucker

回答

6

看來你的U列應該是2對應於「B」,而不是1.請澄清。

你可以嘗試match()

matrix(match(demodata2, LETTERS), nrow(demodata2), dimnames=dimnames(demodata2)) 
#  Q R S T U W 
# [1,] 1 2 NA NA 2 2 
# [2,] 2 2 2 NA 2 2 
# [3,] 2 NA NA NA NA NA 
# [4,] 3 3 3 2 2 3 
# [5,] NA 1 1 3 2 1 
# [6,] 1 2 2 1 NA NA 

你也可以得到這樣的結果與

m <- match(demodata2, LETTERS) 
attributes(m) <- attributes(demodata2) 

再看看m


更新修改後的數據集:

爲您更新的數據,試圖

demodata2[] <- lapply(demodata2, as.numeric) 
demodata2 
# Q R S T U W 
# 1 1 2 NA NA 1 2 
# 2 2 2 2 NA 1 2 
# 3 2 NA NA NA NA NA 
# 4 3 3 3 2 1 3 
# 5 NA 1 1 3 1 1 
# 6 1 2 2 1 NA NA 

現在,你必須在U列1的,因爲每一列單獨因素,因此B是第一個(也是唯一一個)在該列中的值。

+0

我問的問題的精彩答案......但顯然我問了錯誤的問題。首先將demodata2變成數據框(這會自動將字符字段放入因子中),然後您就會問我*表示*的問題。非常感謝,我希望你能幫助解決這個額外的挑戰。 – rucker

+1

@rucker - 更新數據更簡單。做'demodata2 [] < - lapply(demodata2,as.numeric)'現在你在'U'列中有1,因爲每列都是單獨分解的,因此B是第一個(也是唯一的)值 –

+0

非常感謝!簡單?也許。但我一直在這個問題上前進,因此非常感謝您的幫助。 – rucker

3

或者使用dim<-

`dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2))) 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
# [1,] 1 2 NA NA 2 2 
# [2,] 2 2 2 NA 2 2 
# [3,] 2 NA NA NA NA NA 
# [4,] 3 3 3 2 2 3 
# [5,] NA 1 1 3 2 1 
# [6,] 1 2 2 1 NA NA 

如果你需要的列名,你要先做到這兩個步驟中

Res <- `dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2))) 
colnames(Res) <- colnames(demodata2) 
+0

另一種重寫你的行的方法:'矩陣(as.numeric(因子(demodata2)),ncol = ncol(demodata2))' – nicola

+0

@David Arenburg :我問的問題的精彩答案......但顯然我提出了錯誤的問題。首先將demodata2變成數據框(這會自動將字符字段放入因子中),然後您就會問我*表示*的問題。非常感謝,我希望你能幫助解決這個額外的挑戰。 – rucker

4

機械,這是非常相似的'dim<-'回答。更透明一點,但可能效率較低(可能?)。

matrix(as.numeric(factor(demodata2)), ncol = ncol(demodata2)) 

    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 2 NA NA 2 2 
[2,] 2 2 2 NA 2 2 
[3,] 2 NA NA NA NA NA 
[4,] 3 3 3 2 2 3 
[5,] NA 1 1 3 2 1 
[6,] 1 2 2 1 NA NA 
+0

缺少括號... –

+0

哎呀,謝謝。原來'as.vector()'也是不必要的。 – Gregor

+0

我的猜測是''-dim'會比'<-dim'更有效率,因爲它會跳過'nrow'部分,我只是想對它有點光滑:) –

2
apply(demodata2, 2, function(x) 
      as.numeric(factor(x ,levels=unique(as.vector(demodata2))))) 
#--------------- 
     Q R S T U W 
[1,] 1 2 NA NA 2 2 
[2,] 2 2 2 NA 2 2 
[3,] 2 NA NA NA NA NA 
[4,] 3 3 3 2 2 3 
[5,] NA 1 1 3 2 1 
[6,] 1 2 2 1 NA NA 

(我通過得到錯誤的答案是unique在基質不回我所期待的發現。)

+0

我問的問題的精彩答案......但顯然我問了錯誤的問題。首先將demodata2變成數據框(這會自動將字符字段放入因子中),然後您就會問我*表示*的問題。非常感謝,我希望你能幫助解決這個額外的挑戰。 – rucker