无法真正理解以下行为。
>ddd <- data.frame(a=c(2,3,4), b=c(10,20,30)) ## creating a simple dataframe with 2 columns
> ddd
a b
1 2 10
2 3 20
3 4 30
应用
lapply()
给出预期结果如下:
> lapply(ddd, function(x) x*100 )
$a
[1] 200 300 400
$b
[1] 1000 2000 3000
但是,当
is.numeric()
在 FUN 中使用时,它仅适用于第一行。怎么会呢?
> lapply(ddd, function(x) ifelse( is.numeric(x), x*100, x ) )
$a
[1] 200
$b
[1] 1000
当以某种方式将
is.numeric()
与is.na()
结合使用时,它会再次像往常一样工作。
> lapply(ddd, function(x) ifelse( is.numeric(x) & !is.na(x), x*100, x ) )
$a
[1] 200 300 400
$b
[1] 1000 2000 3000
为什么会出现这种情况?
is.numeric(x)
返回单个值。它与
is.na()
一起使用的原因是
is.na()
返回与输入长度相同的对象。当您一起使用它们时,
is.numeric
中的 TRUE 会被回收到正确的长度。
> is.na(ddd$a)
[1] FALSE FALSE FALSE
> is.numeric(ddd$a)
[1] TRUE
> is.numeric(ddd$a) & !is.na(ddd$a)
[1] TRUE TRUE TRUE
正如@jay.sf 在评论中提到的,ifelse()
返回与测试参数长度相同的结果。因此,您的代码仅适用于每列的第一个值。解决此问题的一种方法是将
ifelse()
替换为
if( ) { } else { }
:
lapply(ddd, function(x) if(is.numeric(x)) {x*100} else {x} )