我想比较不同行中的不同单元格,并在条件满足时返回值。
假设以下s_i
=
[,1] [,2] [,3]
[1,] 0.43020494 0.7183179 0.4201009
[2,] 0.08625491 0.3007912 0.8768459
[3,] 0.80012649 0.8448729 0.7131344
我想比较所有的行(对),所以第1,2行; 1,3; 2,3; 2,1; 3,1和3,2行
输出dgpos
包含组合的行号和返回的值。
我想比较行。为第一或第1和第2行组合的第一个
1, if 2b≥1b
0, if 1a≥2c
(1a-2c )/ ((2b-2c) –(1b-1a), otherwise
其中a,b和c是s_i
的列第1行和第2行的R-ish
If (s_i[2,2]>= s_i[1,2])
dgpos[rowindex,3]=1
If (s_i[1,1]>= s_i[2,3])
dgpos[rowindex,3]=0
else (otherwise)
dgpos[rowindex,3] =(s_i[1,1]- s_i[2,3])/((s_i[2,2]-s_i[2,3])-(s_i[1,2]-s_i[1,1]))
我想要的输出包含dgpos[,3]
[,1] [,2] [,3]
[1,] 1 2 0.5168453
[2,] 1 3 1
[3,] 2 3 1
[4,] 2 1 1
[5,] 3 1 0
[6,] 3 2 0.1235813
我有这个:
s_i=matrix(runif(9),3)
dgpos=matrix(0,(dim(s_i)[2]*(dim(s_i)[2]-1)),3)
rowindex=1
for (i in 1:nrow(s_i)) {
for (j in 1:nrow(s_i)) {
if (i!=j)
c1=s_i[i,]
c2=s_i[j+1,]
dgpos[rowindex,1]=i
dgpos[rowindex,2]=j+1
if (c2[2] >= c1[2])
dgpos[rowindex,3]=1
dgpos[rowindex,3] = ifelse ((c1[1]=c2[3]), 0 , c1[1]-c2[3]/((c2[2]-c2[3])-(c1[2]-c1[1])))
rowindex=rowindex+1
}
}
我知道循环不是首选,但此刻(我的r-ish级别)我不知道更好的解决方案。我使用adply
尝试了combn
,没有结果。
MQ:如何比较不同行中的不同单元格并根据几个条件返回值?
感谢您的帮助和赞扬。
答案 0 :(得分:0)
我不保证这正是您想要的逻辑(您的示例和代码之间存在不一致),但这是对您的算法进行矢量化的正确方法:
首先,创建所有行索引组合的data.frame:
n <- nrow(s_i)
dgpos <- rev(expand.grid(row2 = seq_len(n), row1 = seq_len(n)))
dgpos <- subset(dgpos, row1 != row2)
dgpos
# row1 row2
# 2 1 2
# 3 1 3
# 4 2 1
# 6 2 3
# 7 3 1
# 8 3 2
然后,在一个向量化调用中计算结果,嵌套ifelse
:
dgpos <- transform(dgpos, out = { c1 <- s_i[row1, ]
c2 <- s_i[row2, ]
ifelse(c2[,2] >= c1[,2], 1,
ifelse(c1[,1] >= c2[,3], 0,
(c1[,1]-c2[,3]) / ((c2[,2]-c2[,3]) - (c1[,2]-c1[,1])))) })
dgpos
# row1 row2 out
# 2 1 2 0
# 3 1 3 0
# 4 2 1 0
# 6 2 3 0
# 7 3 1 0
# 8 3 2 0
答案 1 :(得分:0)
这要归功于@flodel。毫无疑问,这不是最优雅的解决方案
dgpos = rev(expand.grid(row2 = seq_len(nrow(s_i)), row1 = seq_len(nrow(s_i))))
dgpos = subset(dgpos, row1 != row2)
for (i in 1:nrow(dgpos)) {
c1 = s_i[dgpos$row1[i], ]
c2 = s_i[dgpos$row2[i], ]
dgpos$out[i] = ifelse(c2[2] >= c1[2], 1,
ifelse(c1[1] >= c2[3], 0,
(c1[1]-c2[3]) / ((c2[2]-c2[3]) - (c1[2]-c1[1])))) }
dgpos
# row1 row2 out
# 2 1 2 0.5168453
# 3 1 3 1
# 4 2 1 1
# 6 2 3 1
# 7 3 1 0
# 8 3 2 0.1235813
答案 2 :(得分:0)
我设法使用以下方法重现您想要的输出:
f <- function(i, j, s){
ifelse(s[j,2]>=s[i,2], 1, ifelse(s[i,1]>=s[j,3], 0,
(s[i,1]-s[j,3])/((s[j,2]-s[j,3])-(s[i,2]-s[i,1]))))
}
s_i <- rbind(
c(0.43020494, 0.7183179, 0.4201009),
c(0.08625491, 0.3007912, 0.8768459),
c(0.80012649, 0.8448729, 0.7131344))
y <- combn(nrow(s_i), 2)
dgpos <- t(cbind(y, y[2:1,]))
cbind(dgpos, f(dgpos[,1], dgpos[,2], s_i))
结果:
[,1] [,2] [,3]
[1,] 1 2 0.5168453
[2,] 1 3 1.0000000
[3,] 2 3 1.0000000
[4,] 2 1 1.0000000
[5,] 3 1 0.0000000
[6,] 3 2 0.1235813