假设我有一个矩阵列表:
$`2010`
1 2 3 4
1 0 3 5 6
2 5 1 9 5
3 0 0 0 0
4 10 10 10 0
$`2011`
1 2 3 4
1 0 2 3 6
2 5 0 3 1
3 2 4 0 1
4 2 1 2 1
创建矩阵的代码:
cntry<-c(1,2,3,4)
a<-c(0,5,0,10)
b<-c(3,1,0,10)
c<-c(5,9,0,10)
d<-c(6,5,0,0)
k<-data.frame(a,b,c,d)
k<-as.matrix(k)
dimnames(k)<-list(cntry,cntry)
e<-c(0,5,2,2)
f<-c(2,0,4,1)
g<-c(3,3,0,2)
h<-c(6,1,1,1)
l<-data.frame(e,f,g,h)
l<-as.matrix(l)
dimnames(l)<-list(cntry,cntry)
list<-list(k,l)
names(list)<-2010:2011
我想在每一行中保留两个最高值,并将同一行中其他单元格的剩余较小值替换为0。
如果有两个以上的单元格具有最高值,我想保留所有这些单元格(例如:10 10 10 0-> 10 10 10 0,5 1 9 5 - > 5 0 9 5)。该行的所有其他单元格应再次设置为0。
结果应如下所示:
$`2010`
1 2 3 4
1 0 0 5 6
2 5 0 9 5
3 0 0 0 0
4 10 10 10 0
$`2011`
1 2 3 4
1 0 0 3 6
2 5 0 3 0
3 2 4 0 0
4 2 0 2 0
我不确定如何处理这个问题,所以非常欢迎任何帮助!
答案 0 :(得分:4)
这是一种方法:
lapply(list, function(x) {
t(apply(x, 1, function(y) {
y[!y %in% tail(sort(y), 2)] <- 0
y
}))
})
## $`2010`
## 1 2 3 4
## 1 0 0 5 6
## 2 5 0 9 5
## 3 0 0 0 0
## 4 10 10 10 0
##
## $`2011`
## 1 2 3 4
## 1 0 0 3 6
## 2 5 0 3 0
## 3 2 4 0 0
## 4 2 0 2 0
这可以通过迭代列表的元素(使用lapply
),依次将每个元素视为对象x
,然后迭代x
的行(带{ {1}})调用行apply(x, 1, ...)
并对其应用函数。
应用于列表元素y
的行y
的函数是:
x
标识行的两个具有最高价值的元素(function(y) {
y[y < tail(sort(y), 2)] <- 0
y
}
),返回一个逻辑向量,指示tail(sort(y), 2)
中哪些元素不在该集合中(y
) ,使用该逻辑向量将向量y < ...
的元素子集,并将y
分配给这些元素。最后,它返回修改后的0
。