0

我有一个大型数据框,我想使用 reshape2 包中的 dcast() 函数将其转换为宽格式数据。但是,值列是字符列,但其中的一些值是字符串格式的数值。我尝试创建一个自定义聚合函数来处理这个问题,如果有数字条目,它将返回平均值,但如果所有条目都是非数字,则返回第一个条目。尽管该函数似乎可以工作,但在用作 fun.aggregate 时会返回错误。下面是一个带有较小玩具示例的代码来演示。我想要的是一个 3x5 数据框,其中第一列是分组变量、3 列数值和 1 列字符值。

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 (indices, fun, .default) 中的错误:值必须是“字符”类型,但 FUN(X[[1]]) 结果是“双”类型

4

1 回答 1

1

这是 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)
于 2016-06-22T15:00:41.973 回答