2015-04-22 31 views
3

我正在處理具有1900列和大約280,000行的data.table。使用data.table set()將所有列從整數轉換爲數字

目前,數據完全是「整數」,但我希望它們明確地「數字」,以便稍後將它傳遞給bigcor()函數。顯然,bigcor()只能處理「數字」而不是「整數」。

我曾嘗試:

full.bind <- full.bind[,sapply(full.bind, as.numeric), with=FALSE] 

不幸的是,我得到的錯誤:

Error in `[.data.table`(full.bind, , sapply(full.bind, as.numeric), with = FALSE) : 
    j out of bounds 

所以,我嘗試使用data.table set()函數,但我得到的錯誤:

Error in set(full.bind, value = as.numeric(full.bind)) : 
    (list) object cannot be coerced to type 'double' 

我已經創建了一個簡單的可重複的例子。請記住,實際的列不是「a」,「b」或「c」;它們是非常複雜的列名,因此單獨引用列不是一種可能性。

dt <- data.table(a=1:10, b=1:10, c=1:10) 

所以,我最後的問題是:

1)爲什麼我的sapply技術不行? (什麼是「j越界」錯誤?) 2)爲什麼set()技術不是? (爲什麼data.table不能強制爲數字?) 3)bigcor()函數是否需要數字對象,還是存在另一個問題?

+8

收到答案後,不會刪除問題。你有免費的幫助,所以請儘量感激。 –

+1

我實際上試圖在發佈後立即刪除它,因爲我在其他地方找到了答案。對於那個很抱歉! –

+0

不確定'data.frame'和'data.table'之間的差異(所以也許這是不相關的,對不起!),但是我發現'dplyr'在這裏很有幫助:'mutate_if(df,is.integer,as。數字)將所有整數列轉換爲數字:乾淨,簡潔,快捷。 – dwanderson

回答

11

使用.SD和按引用賦值:

library(data.table) 
dt <- data.table(a=1:10, b=1:10, c=1:10) 
sapply(dt, class) 
#  a   b   c 
#"integer" "integer" "integer" 

dt[, names(dt) := lapply(.SD, as.numeric)] 
sapply(dt, class) 
#  a   b   c 
#"numeric" "numeric" "numeric" 

set僅適用於在這裏一列(注意文檔,不說j是可選的),因爲每次更換列有產生。如果要使用它,則需要遍歷列(例如,使用for循環)。它可能更好,因爲它需要更少的內存(額外的內存需要對應於一列,而對於整個data.table需要額外的內存,第一種方法)。

for (k in seq_along(dt)) set(dt, j = k, value = as.character(dt[[k]])) 
sapply(dt, class) 
#   a   b   c 
#"character" "character" "character" 

然而,bigcor(從包繁殖)需要一個矩陣作爲輸入,並且一個data.table不是矩陣。所以,你的問題不是列類型,但你需要使用as.matrix(dt)

+1

'set()'可以同時處理多個列,但每個列都必須生成'value',但是更喜歡你的'set()'方法,因爲它需要額外一個雙列的內存。帶'lapply()'的':='必須在替換之前將每列轉換爲數字(這要求整個數據的大小以double爲單位)。 – Arun

+1

@阿倫謝謝。我試圖將其添加到答案中。不過,我更喜歡第一種更好的語法。我很少處於沒有足夠內存的情況下。 – Roland

+0

如果你只想改變一些列,你怎麼做? 例如,我想排除第三個: dt [,名稱(.SD):= lapply(.SD,as.numeric),.SDcols =!c(3)] 我得到此錯誤: .data.table'(dt,,':='(names(.SD),lapply(.SD,as.integer)),: LHS:=不是列名('字符')或位置'.data.table'(integer)或'numeric') And dt [,names(dt):= lapply(.SD,as.numeric),.SDcols =!c(3)]給出了另一個錯誤: 在'[.data.table (dt,,':='(names(dt),lapply(.SD,as.integer)),: 提供3列分配一個值列表(長度爲2)(循環剩下1項) – skan