在R

时间:2016-01-19 19:10:49

标签: r loops lapply sapply

我试图在R中编写一个简化的函数来比较矩阵中的多个列。在R中执行此操作的最佳方法是什么?最有可能使用申请。

我已经看到这个问题多次出现,但对于写这个问题的最佳方式存在一些相互矛盾的看法。

for ( j in 2:ncol(net) )
{
    for ( i in 1:nrow(net) )
    {
            net[i,j] <- min(net[i,j],net[i,1])
    }
}

具有以下

的矩阵的结束输出
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    2    3
[3,]    3    2    3

将是

     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    2    3

3 个答案:

答案 0 :(得分:1)

我们可以unlist列&#34; net&#34;除了第一列(net[-1])之外,将第一列复制为与unlist ed列相同的长度,并使用pmin获取{{1}的相应元素的最小值}}

vectors

如果我们需要pmin(unlist(net[-1], use.names=FALSE), net[,1][row(net[-1])]) #[1] 2 2 7 5 2 2 2 6 5 3 2 1 0 5 1 解决方案,

lapply

使用OP的unlist(lapply(net[-1], function(x) pmin(x, net[,1])), use.names=FALSE) 循环

for

更新

由于OP提到这不会给出预期的输出,因此在OP的帖子中尝试使用新数据

for ( i in 2:ncol(net) ){
   for ( j in 1:nrow(net) ){
     print(min(net[j,i],net[j,1]))
   }
 }
#[1] 2
#[1] 2
#[1] 7
#[1] 5
#[1] 2
#[1] 2
#[1] 2
#[1] 6
#[1] 5
#[1] 3
#[1] 2
#[1] 1
#[1] 0
#[1] 5
#[1] 1

数据

net <- cbind(1:3, 2, 3)

cbind(net[,1],pmin(unlist(net[,-1], use.names=FALSE), 
           net[,1][row(net[,-1])]))
#      [,1] [,2] [,3]
#[1,]    1    1    1
#[2,]    2    2    2
#[3,]    3    2    3

答案 1 :(得分:0)

如果没有NA你可以做

net <- head(airquality, 4) # example data
for (j in 1:nrow(net)) net[j, net[j,]>net[j,1]] <- net[j,1]
net

答案 2 :(得分:0)

这是一个sapplyifelse的版本(矢量化,woo),它可能更快,并以可预测的方式处理NA值:

sapply(X = seq(to = ncol(x = net)), FUN = function(j){
  net[,j] <- ifelse(test = net[,1] < net[,j], yes = net[,1], no = net[,j])
})

一些示例数据

net <- head(airquality)
net
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6

结果:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   41   41  7.4   41    5    1
[2,]   36   36  8.0   36    5    2
[3,]   12   12 12.0   12    5    3
[4,]   18   18 11.5   18    5    4
[5,]   NA   NA   NA   NA   NA   NA
[6,]   28   NA 14.9   28    5    6

注意:我已经指定了几乎所有的参数名称,因为我发现这使得大多数代码更快。如果你不关心时间,可以使用更简单的[可能更易读]版本:

sapply(seq(ncol(net)), function(j){
    net[,j] <- ifelse(net[,1] < net[,j], net[,1], net[,j])
})