2012-03-13 57 views
3

这是一个非常简单的问题,但我希望有人能够帮助我避免多余的不必要的代码行。我有一个简单的数据帧:乘以列时删除NA​​

Df.1 <- data.frame(A = c(5,4,7,6,8,4),B = (c(1,5,2,4,9,1)),C=(c(2,3,NA,5,NA,9))) 

我想要做的是产生一个额外的列是A,B和C,的倍增,我会再cbind原来的数据帧。

所以,我通常会使用:

attach(Df.1) 
D<-A*B*C 

但很明显,其中NA的列C,我得到一个NA变量D.我不想排除所有的NA行,而只是忽略此列中的NA值(然后D中的值将简单地是A和B的乘积,或者其中C是可用的,A * B * C

我知道我可以简单地用1代替NA ,所以计算保持不变,或使用if语句,但是我正在寻找这样做的简单方法是什么?

任何想法?

+0

如何'd < - A * B *(!C * is.na(C)+ 1 * is.na(C))',它是使用'if'周围偷偷摸摸。 – 2012-03-13 11:21:51

+0

这将是伟大的,但我恐怕@CarlWitthoft代码行不起作用。 – 2012-03-13 11:32:16

+0

我的歉意 - 我现在无法测试/调试。你能告诉我什么错误(或输出错误)? – 2012-03-13 13:21:14

回答

3

您可以使用prod,它有一个na.rm参数。要通过行使用apply做到这一点:

apply(Df.1,1,prod,na.rm=TRUE) 
[1] 10 60 14 120 72 36 
+0

这真的很有趣@詹姆斯,我从来没有使用'prod'之前 - 我可以问什么'1'用于?另外,如果我的数据集中有其他列,但仍然只想要多个A,B和C - 是否有一种指定我希望它找到产品的列的方法? – 2012-03-13 11:35:18

+0

@KatieT 1告诉'apply'通过'MARGIN'参数逐行工作。为了限制列的数量,您只需要将想要使用的列传递给“应用”,但这可以内联完成:'apply(Df.1 [c(“A”,“B”,“C” )],1,prod,na.rm = T)' – James 2012-03-13 11:43:46

+0

这正是我想要的 - 谢谢@詹姆斯! – 2012-03-13 12:03:49

2

正如@詹姆斯说,督促和应用都可以工作,但你并不需要浪费内存将其存储在一个单独的变量,甚至cbinding它

Df.1$D = apply(Df.1, 1, prod, na.rm=T) 

直接在数据框中分配新变量将工作。

> Df.1 <- data.frame(A = c(5,4,7,6,8,4),B = (c(1,5,2,4,9,1)),C=(c(2,3,NA,5,NA,9))) 
> Df.1 
    A B C 
1 5 1 2 
2 4 5 3 
3 7 2 NA 
4 6 4 5 
5 8 9 NA 
6 4 1 9 
> Df.1$D = apply(Df.1, 1, prod, na.rm=T) 
> Df.1$D 
[1] 10 60 14 120 72 36 
> Df.1 
    A B C D 
1 5 1 2 10 
2 4 5 3 60 
3 7 2 NA 14 
4 6 4 5 120 
5 8 9 NA 72 
6 4 1 9 36