R获取矩阵中每行的最小值,并返回行和列名称

时间:2022-08-22 13:50:11

I have a matrix like so:

我有一个像这样的矩阵:

R获取矩阵中每行的最小值,并返回行和列名称

Only in reality it is hundreds or thousands of values.

实际上只有数百或数千个值。

What I need to do is return the minimum value for each row, along with the row/col name.

我需要做的是返回每行的最小值,以及行/列名称。

So for row 1 in the example, "BAC", the minimum is 0.92 for BAC/CSCO, so I need to return something like:

因此对于示例中的第1行“BAC”,BAC / CSCO的最小值为0.92,因此我需要返回类似于:

BAC/CSCO 0.92

And then repeat this for each row in the matrix.

然后对矩阵中的每一行重复此操作。

Assistance is greatly appreciated. I think apply is the trick, but I can't quite get the right combination.

非常感谢协助。我认为申请是诀窍,但我无法得到正确的组合。

2 个解决方案

#1


14  

X <- matrix(runif(20), nrow=4)
rownames(X) <- paste0("foo", seq(nrow(X)))
colnames(X) <- paste0("bar", seq(ncol(X)))

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

print(X)
print(result)

will give you:

会给你:

          bar1      bar2       bar3       bar4      bar5
foo1 0.2085419 0.6290522 0.12730378 0.17775105 0.3239684
foo2 0.8061464 0.7948392 0.09330563 0.06698921 0.5557932
foo3 0.1790950 0.7788139 0.35787944 0.39117325 0.2578457
foo4 0.9099254 0.4048508 0.54791272 0.38674301 0.3272156

and

     [,1]        [,2]                
[1,] "foo1/bar3" "0.127303782384843" 
[2,] "foo2/bar4" "0.0669892099685967"
[3,] "foo3/bar1" "0.179094966035336" 
[4,] "foo4/bar5" "0.327215566998348" 

#2


3  

Or here with apply()

或者在这里使用apply()

#CREATE THE DATA
df<-data.frame(matrix(data=round(x=rnorm(100,10,1),digits=3),nrow=10),
           row.names=c("A","B","C","D","E","F","G","H","I","J"))
colnames(df)<-c("AD","BD","CD","DD","ED","FD","GD","HD","ID","JD")

#RUN THROUGH THE DF
mins<-apply(df,2,function(x)return(array(which.min(x))))
mins<-data.frame(col=names(mins),row=mins)
df$mins<-apply(mins,1,FUN=function(x)return(paste(x["col"],
                                     rownames(df[as.numeric(x["row"]),]),
                                     df[as.numeric(x["row"]),x["col"]],
                                     sep="/")))
> df
      AD     BD     CD     DD     ED     FD     GD     HD     ID     JD       mins
A  9.292 11.568 10.489  9.512  7.755  8.545  9.989  9.660  9.240  9.913 AD/G/8.477
B 11.972 11.297  9.221 10.936  8.665  9.154 10.620  8.335 11.149 11.382 BD/F/7.588
C  9.910  9.762 11.744  8.938 11.283  8.750  8.719 10.929  9.158 10.168 CD/G/8.481
D  9.986  8.776  9.922  9.016 10.691 10.667  9.876 11.417 10.391 10.823 DD/C/8.938
E  8.877  9.672  9.024 10.424  9.033  8.709 10.176  9.937 10.891  9.779 ED/A/7.755
F  8.656  7.588 10.071  9.549  8.654  7.965 11.693  9.019  8.665  8.971 FD/F/7.965
G  8.477  9.686  8.481 10.925 11.034 12.021 10.642 11.087 10.398  9.989 GD/C/8.719
H  9.578 11.660 10.864  9.801  9.188 11.006 11.282 10.139  9.888  8.775 HD/B/8.335
I 11.361 10.131 10.502 11.195 11.802 10.817 10.141  9.614 10.676  7.404 ID/F/8.665
J 11.754 11.096  9.645 10.496 11.772  9.336  8.887 11.124  9.211 11.169 JD/I/7.404    

#1


14  

X <- matrix(runif(20), nrow=4)
rownames(X) <- paste0("foo", seq(nrow(X)))
colnames(X) <- paste0("bar", seq(ncol(X)))

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

print(X)
print(result)

will give you:

会给你:

          bar1      bar2       bar3       bar4      bar5
foo1 0.2085419 0.6290522 0.12730378 0.17775105 0.3239684
foo2 0.8061464 0.7948392 0.09330563 0.06698921 0.5557932
foo3 0.1790950 0.7788139 0.35787944 0.39117325 0.2578457
foo4 0.9099254 0.4048508 0.54791272 0.38674301 0.3272156

and

     [,1]        [,2]                
[1,] "foo1/bar3" "0.127303782384843" 
[2,] "foo2/bar4" "0.0669892099685967"
[3,] "foo3/bar1" "0.179094966035336" 
[4,] "foo4/bar5" "0.327215566998348" 

#2


3  

Or here with apply()

或者在这里使用apply()

#CREATE THE DATA
df<-data.frame(matrix(data=round(x=rnorm(100,10,1),digits=3),nrow=10),
           row.names=c("A","B","C","D","E","F","G","H","I","J"))
colnames(df)<-c("AD","BD","CD","DD","ED","FD","GD","HD","ID","JD")

#RUN THROUGH THE DF
mins<-apply(df,2,function(x)return(array(which.min(x))))
mins<-data.frame(col=names(mins),row=mins)
df$mins<-apply(mins,1,FUN=function(x)return(paste(x["col"],
                                     rownames(df[as.numeric(x["row"]),]),
                                     df[as.numeric(x["row"]),x["col"]],
                                     sep="/")))
> df
      AD     BD     CD     DD     ED     FD     GD     HD     ID     JD       mins
A  9.292 11.568 10.489  9.512  7.755  8.545  9.989  9.660  9.240  9.913 AD/G/8.477
B 11.972 11.297  9.221 10.936  8.665  9.154 10.620  8.335 11.149 11.382 BD/F/7.588
C  9.910  9.762 11.744  8.938 11.283  8.750  8.719 10.929  9.158 10.168 CD/G/8.481
D  9.986  8.776  9.922  9.016 10.691 10.667  9.876 11.417 10.391 10.823 DD/C/8.938
E  8.877  9.672  9.024 10.424  9.033  8.709 10.176  9.937 10.891  9.779 ED/A/7.755
F  8.656  7.588 10.071  9.549  8.654  7.965 11.693  9.019  8.665  8.971 FD/F/7.965
G  8.477  9.686  8.481 10.925 11.034 12.021 10.642 11.087 10.398  9.989 GD/C/8.719
H  9.578 11.660 10.864  9.801  9.188 11.006 11.282 10.139  9.888  8.775 HD/B/8.335
I 11.361 10.131 10.502 11.195 11.802 10.817 10.141  9.614 10.676  7.404 ID/F/8.665
J 11.754 11.096  9.645 10.496 11.772  9.336  8.887 11.124  9.211 11.169 JD/I/7.404