2016-06-22 35 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) 
相关问题