2016-06-22 36 views
0

我有一個大數據框,我想用reshape2包中的dcast()函數將其轉換爲寬格式的數據。但是,值列是一個字符列,但其中的某些值是字符串格式的數值。我試圖創建一個自定義集合函數來處理這個問題,如果有數字條目,它將返回平均值,但如果所有條目都是非數字值,則返回第一個條目。儘管該函數似乎可行,但在作爲fun.aggregate使用時會返回錯誤。下面是一個較小的玩具示例代碼來演示。我想要的是一個3x5數據框,第一列是分組變量,三列數字值和一列字符值。如何爲可以處理字符和數字輸入的dcast創建自定義聚合函數?

mean_with_char <- function(x) { 
xnum <- as.numeric(x) 
if (any(!is.na(xnum))) mean(xnum, na.rm=TRUE) else x[1] 
} 

library(reshape2) 

fakedata <- data.frame(grp1 = rep(letters[1:3],times=20), grp2 = rep(LETTERS[17:20],each=15), val=rnorm(60)) 
fakedata$val[46:60] <- rep(c('foo','bar','bla','bla','bla','bla'), length.out=15) 

# This returns a 3x5 data frame with NA entries. 
dcast(fakedata, grp1 ~ grp2, value.var='val', fun.aggregate=mean) 

# This returns an error. 
dcast(fakedata, grp1 ~ grp2, value.var='val', fun.aggregate=mean_with_char) 

錯誤vapply(指數,樂趣,.DEFAULT):值必須是 類型 '字符',但FUN(X [[1]])結果是類型 '雙'

+1

它看起來像'vapply'希望所有的結果是一個變量類型,而不是混合。一個解決辦法是讓你的數字(手段)字符,然後轉換類型。我已經使用了'readr :: type_convert'這類的東西。 – aosmith

回答

0

這是由aosmith建議的解決方法。 mean_with_char函數僅返回字符輸出,而numstring2num函數將數字字符串轉換爲數字。

mean_with_char <- function(x) { 
    xnum <- as.numeric(x) 
    if (any(!is.na(xnum))) as.character(mean(xnum, na.rm=TRUE)) else x[1] 
} 

library(reshape2) 

fakedata <- data.frame(grp1 = rep(letters[1:3],times=20), grp2 = rep(LETTERS[17:20],each=15), val=rnorm(60)) 
fakedata$val[46:60] <- rep(c('foo','bar','bla','bla','bla','bla'), length.out=15) 

fakecast <- dcast(fakedata, grp1 ~ grp2, value.var='val', fun.aggregate=mean_with_char) 

# Function to change columns in a df that only consist of numeric strings to numerics. 
numstring2num <- function(x) { 
    xnum <- as.numeric(x) 
    if (!any(is.na(xnum)) & !is.factor(x)) xnum else x 
} 


fakecast[] <- lapply(fakecast[], numstring2num) 
相關問題