使用if-else条件的向量乘以数据帧

时间:2013-09-25 18:44:21

标签: r

我正在为线性回归模型执行Box-Cox转换,但在R中实现此问题时遇到了一些问题。

我已经获得了Box-Cox的最佳lambda值。我想在R中执行以下操作:

opt.lambda.test<- lapply(temp.list, function(x) with(x, x[which.max(y)]))

从Box-Cox中提取最佳lambda。 temp.list是回归结果列表。

opt.lambda.test
[[1]]
[1] 0.77

[[2]]
[1] 3.46

然后我把它变成一个矢量:

vec.lambda <- unlist(opt.lambda.test)

我有一个数据框,在本例中,有2列。这是一个片段:

       x_1       x_2
[1,]  99.81974  99.43289
[2,] 102.20328 103.68653
....

完整的数据框只是:

 x_1 <- rnorm(100,mean=100,sd=1)
 x_2 <- rnorm(100,mean=100,sd=4)
 x.temp1<-cbind(x_1,x_2)

在我正在分析的实际数据中,列的行数不会相同。

任何人,我希望数据框的每一列都被提升到vec.lambda中值的幂。在这种情况下,x_1 $ ^ {0.77} $和x_2 $ ^ {3.46} $依此类推。 vec.lamba的长度始终等于数据帧的列数。

但是,如果vec.lambda == 0我希望将列转换为:$ log(x_ {i})$。我不能让第一部分工作,所以我希望在数据框操作的条件方面和普通的旧数据框操作方面提供一些帮助。

x.test.1 <- apply(x.temp1,2,function(x) x^vec.lambda)

这是我天真的尝试不起作用吗?

1 个答案:

答案 0 :(得分:1)

您正在将函数应用于每列而不是每行。如果您将2更改为1,那么您几乎可以拥有自己想要的内容;你实际上有你想要的转置(因为apply将每个结果放在一列中),但只是转换结果很容易:

t(apply(x.temp1,1,function(x) x^vec.lambda))

但是,还有其他方法可能更快。 R将沿着列再循环值,因此您可以转置矩阵(以便列有两行),将其提升到vec.lambda(这将自动为每列重复),然后转置结果:

t(t(x.temp1) ^ vec.lambda)

你也可以创建一个与x.temp1长度相同的向量,然后将x.temp1提升到这个:

x.temp1 ^ rep(vec.lambda, each=nrow(x.temp1))

甚至是与x.temp1尺寸相同的矩阵,因此x.temp1[i, j]应该提升为mat.lambda[i, j]。也许这是最明确的方法:

mat.lambda <- matrix(vec.lambda, ncol=2, nrow=nrow(x.temp1), byrow=TRUE)
x.temp1 ^ mat.lambda

至于您希望在vec.lambda为零时执行其他操作,一种方法是使用ifelse

mat.lambda <- matrix(vec.lambda, ncol=2, nrow=nrow(x.temp1), byrow=TRUE)
ifelse(mat.lambda==0, log(x.temp1), x.temp1 ^ mat.lambda)