简体   繁体   中英

R: Apply family that deletes columns as part of the function

I am trying to iterate through each row in a matrix, find the column with the minimum value and the column name and then delete that column after it has been used so that a new minimum can be calculated. The correct answer should look like this:

result
1/1   50
2/2   61
3/3   72
4/4   83

Test_Matrix <- matrix(c(50:149), ncol = 10 , byrow=FALSE)
 Names <- c(1:10)
 colnames(Test_Matrix) <- Names
 rownames(Test_Matrix) <- Names


result <- t(sapply(seq(nrow(Test_Matrix)), function(i) {
  j <- which.min(Test_Matrix[i,])
  c(paste(rownames(Test_Matrix)[i], colnames(Test_Matrix)[j], sep='/'), Test_Matrix[i,j])
  drops <- colnames(Test_Matrix)[j]
  Test_Matrix[ , !(names(Test_Matrix) %in% drops)]
}))
result

Second question is that I would like to choose the order of the rows during the iteration so that it chooses to go to the next row that had the same name as the column name. For example, if the column with the minimum was named 5, column 5 would be deleted and the minimum for the row named 5 would be calculated next.

Wondering if this is possible and if a loop is needed for these calculations.

As a new R user, I appreciate any help. Thanks!

For the first part of your question:

Test_Matrix <- matrix(c(50:149), ncol = 10 , byrow=FALSE)
Names <- c(1:10)
colnames(Test_Matrix) <- Names
rownames(Test_Matrix) <- Names

result <- matrix(nrow=0, ncol=2)

for (i in 1:nrow(Test_Matrix)) {
  Test_Matrix <- as.matrix(Test_Matrix) #when Test_Matrix has only 1 column R converts it into a vector
  j <- which.min(Test_Matrix[i, ])
  result <- rbind(result, c(paste(rownames(Test_Matrix)[i], 
                                  colnames(Test_Matrix)[j], sep='/'), 
                            as.numeric(Test_Matrix[i,j])))
  Test_Matrix <- Test_Matrix[, -j] #remove column j
}

result
##      [,1]  [,2] 
## [1,] "1/1" "50" 
## [2,] "2/2" "61" 
## [3,] "3/3" "72" 
## [4,] "4/4" "83" 
## [5,] "5/5" "94" 
## [6,] "6/6" "105"
## [7,] "7/7" "116"
## [8,] "8/8" "127"
## [9,] "9/9" "138"
##[10,] "10/" "149"

Edit: For the second part, instead of the for loop, you can use this:

i <- 1
while(length(Test_Matrix)>0) {
  Test_Matrix <- as.matrix(Test_Matrix)
  j <- which.min(Test_Matrix[i, ])
  result <- rbind(result, c(paste(rownames(Test_Matrix)[i], 
                                  colnames(Test_Matrix)[j], sep='/'), 
                            as.numeric(Test_Matrix[i,j])))
  Test_Matrix <- Test_Matrix[, -j]
  i <- as.numeric(names(j))+1
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM