apply()为每列提供NA值
问题描述:
最近我一直有这个奇怪的问题apply
。请看下面的例子:apply()为每列提供NA值
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
来对data.frame
的每一列函数应用fun
(比如,mean
)。如果data.frame
是只包含numeric
值,我没有任何问题:我的含data.frame
numeric
和character
数据当试图
apply(cars, 2, mean)
speed dist
15.40 42.98
但是,它忽视了:
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
当然,我期待character
列的NA
列,但是我想要获得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
答
为?apply
描述的第一句:
如果X不是数组,但一个类的一个对象,具有一个非空暗淡 值(如数据帧) ,如果它是二维的(例如,数据帧)或通过数组asyray应用,尝试通过as.matrix将它强制转换为数组 或通过 as.array。
矩阵只能是R中的一种类型。当数据帧被强制为矩阵时,如果甚至有单个字符列,则所有内容都会以字符结尾。
我想我欠你一个替代的描述,所以在这里你去。数据帧实际上只是列表,所以如果要将函数应用于每列,请改为使用lapply
或sapply
。
答
apply
工作在一个矩阵上,并且矩阵必须全部是一种类型。所以df
正在被转换成一个矩阵,并且由于它包含一个字符,所有的列都变成了字符。
> apply(df, 2, class)
speed dist foo
"character" "character" "character"
为了得到你想要的东西,检查出plyr
的colwise
和numcolwise
功能。
> numcolwise(mean)(df)
speed dist
1 15.4 42.98
答
您正在将一个函数应用于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
你也可以使用'suppressWarnings(sapply(df,mean))'去除警告。然而,这会抑制任何警告,而您的版本只会抑制我们知道会发生的警告,并且不关心,因此您的警告可能是更好的解决方案。 – Dason 2012-04-02 22:10:01