跨 R 中的多列应用函数
Apply function across mulitple columns in R
我正在尝试在 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
我们可以 unlist
除了第一列 (net[-1]
) 之外的 "net" 列,将第一列复制为与 unlist
ed 列相同的长度,并使用 pmin
获取 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
解决方案,
unlist(lapply(net[-1], function(x) pmin(x, net[,1])), use.names=FALSE)
使用 OP 的 for
循环
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
更新
正如 OP 提到的那样,这没有给出预期的输出,尝试使用 OP post
中显示的新数据
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
数据
set.seed(24)
net <- as.data.frame(matrix(sample(0:9, 4*5, replace=TRUE), ncol=4))
如果没有NA
你可以做
net <- head(airquality, 4) # example data
for (j in 1:nrow(net)) net[j, net[j,]>net[j,1]] <- net[j,1]
net
这是一个带有 sapply
和 ifelse
的版本(矢量化,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])
})
我正在尝试在 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
我们可以 unlist
除了第一列 (net[-1]
) 之外的 "net" 列,将第一列复制为与 unlist
ed 列相同的长度,并使用 pmin
获取 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
解决方案,
unlist(lapply(net[-1], function(x) pmin(x, net[,1])), use.names=FALSE)
使用 OP 的 for
循环
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
更新
正如 OP 提到的那样,这没有给出预期的输出,尝试使用 OP post
中显示的新数据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
数据
set.seed(24)
net <- as.data.frame(matrix(sample(0:9, 4*5, replace=TRUE), ncol=4))
如果没有NA
你可以做
net <- head(airquality, 4) # example data
for (j in 1:nrow(net)) net[j, net[j,]>net[j,1]] <- net[j,1]
net
这是一个带有 sapply
和 ifelse
的版本(矢量化,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])
})