我最近遇到了apply
这个奇怪的问题。请考虑以下示例:
set.seed(42)
df <- data.frame(cars, foo = sample(LETTERS[1:5], size = nrow(cars), replace = TRUE))
head(df)
speed dist foo
1 4 2 E
2 4 10 E
3 7 4 B
4 7 22 E
5 8 16 D
6 9 10 C
我想使用apply
在fun
的每一列上应用函数mean
(例如data.frame
)。如果data.frame
仅包含numeric
值,我没有任何问题:
apply(cars, 2, mean)
speed dist
15.40 42.98
但是,在尝试使用包含data.frame
和numeric
数据的character
时,它似乎失败了:
apply(df, 2, mean)
speed dist foo
NA NA NA
Warning messages:
1: In mean.default(newX[, i], ...) :
argument is not numeric or logical: returning NA
2: In mean.default(newX[, i], ..) :
argument is not numeric or logical: returning NA
3: In mean.default(newX[, i], ...) :
argument is not numeric or logical: returning NA
当然,我希望获得NA
列的character
,但我希望获得numeric
列的值。
sapply(df, class)
speed dist foo
"numeric" "numeric" "factor"
任何指针都会受到赞赏,因为我觉得我错过了一些非常明显的东西!
> sessionInfo()
R version 2.14.1 (2011-12-22)
Platform: x86_64-unknown-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_GB.UTF-8 LC_COLLATE=en_GB.UTF-8
[5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8
[7] LC_PAPER=C LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
答案 0 :(得分:10)
?apply
说明的第一句话说:
如果X不是数组,而是具有非null暗淡的类的对象 值(例如数据框)应用尝试将其强制转换为数组 如果它是二维的(例如,数据帧)或通过,则通过as.matrix as.array。
矩阵只能是R中的单一类型。当数据框被强制转换为矩阵时,如果只有一个字符列,则所有内容都以字符结尾。
我想我欠你一个替代品的描述,所以你走了。数据框实际上只是列表,因此如果要将函数应用于每列,请改用lapply
或sapply
。
答案 1 :(得分:3)
apply
适用于矩阵,矩阵必须属于所有类型。所以df
被转换为矩阵,因为它包含一个字符,所有列都变成了字符。
> apply(df, 2, class)
speed dist foo
"character" "character" "character"
要获得所需内容,请查看colwise
中的numcolwise
和plyr
功能。
> numcolwise(mean)(df)
speed dist
1 15.4 42.98
答案 2 :(得分:2)
您正在data.frame的列上应用函数。由于data.frame是一个列表,因此您可以使用lapply
或sapply
代替apply
:
sapply(df, mean)
speed dist foo
15.40 42.98 NA
Warning message:
In mean.default(X[[3L]], ...) :
argument is not numeric or logical: returning NA
您可以在计算平均值之前使用测试类数字的匿名函数来删除警告消息:
sapply(df, function(x)ifelse(is.numeric(x), mean(x), NA))
speed dist foo
15.40 42.98 NA