为点 R 生成圆形边界
generate circular boundary for points R
我正在努力围绕图像中 4 个不同的感兴趣区域设置边界 - 图像和数据采用 0-1 归一化 space,具有四个大小相同的象限。设置方形边界很容易:
df.all$ROI <- ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_left"),
ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_left"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_right"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_right"),
c("other")))))
但是,我想在每个象限 (.25, .25; .25, .75; .75, .25; . 75, .75) 提供相同的输出。
示例数据:
x_pred_normalized <- rnorm(1000, mean=.5, sd=.5)
y_pred_normalized <- rnorm(1000, mean=.5, sd=.5)
df.all <- as.data.frame(cbind(x_pred_normalized, y_pred_normalized))
df.all$ROI_square <- ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_left"),
ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_left"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_right"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_right"),
c("other")))))
期望的输出:
x_pred_normalized y_pred_normalized ROI_square ROI_circle
.99 .99 upper_right other
.51 .51 upper_right other
.25 .25 lower_left lower_left
您的示例不会产生您描述的数据。并且你永远不应该在 data.frame
的调用中使用 cbind
除非有一个数据框对象作为参数之一。这是一个符合您描述的数据框结构(并且足够小,不会在测试时用无用的输出填满您的控制台):
df.all <- data.frame(
x_pred_normalized = pmax( 0, pmin( rnorm(10, mean=.5, sd=.5), 0.99999)),
y_pred_normalized = pmax( 0, pmin( rnorm(10, mean=.5, sd=.5), 0.99999)) )
# all values between 0 and .99999
我发现深度嵌套的 ifelse
结构非常难以调试并且浪费了 space,而使用两列矩阵来 select 字符矩阵中的项目更容易理解.索引数字矩阵中的列是用 findInterval 构造的,因此它将被矢量化并且在时间和 space.
上都更加高效
df.all$quad <- matrix(c("First", "Third","Second","Fourth"), ncol=2)[ cbind(
findInterval(df.all$x_pred_normalized,c( 0, .5, 1,Inf) ),
findInterval(df.all$y_pred_normalized,c( 0, .5,1,Inf) ) )]
#--------------
> df.all
x_pred_normalized y_pred_normalized quad
1 0.78886879 0.3063979 Third
2 0.48122193 0.5440334 Second
3 0.85496224 0.4849327 Third
4 0.01457113 0.5116597 Second
5 0.76936612 0.7424495 Fourth
6 0.99999000 0.4544564 Third
7 0.55473184 0.0000000 Third
8 0.99967092 0.7843946 Fourth
9 0.72561140 0.3985747 Third
10 0.17755530 0.1337408 First
对于 circle-containment 列,我将使用逻辑测试乘以索引值,该索引值可用于通过布尔运算从向量中提取值:
dist= function(x,y)
df.all$circle <- with( df.all, c("other", "First", "Second", "Third", "Fourth")[
1 + # value when all subsequent tests are FALSE
1*(sqrt( (x_pred_normalized-0.25)^2+(y_pred_normalized-0.25)^2) <=0.25) +
# above should be should be 1 (TRUE) for lower-rt; else 0
2*(sqrt( (x_pred_normalized-0.25)^2+ (y_pred_normalized-0.75)^2) <=0.25)+
3*(sqrt( (x_pred_normalized-0.75)^2+(y_pred_normalized-0.25)^2) <=0.25)+
4*(sqrt( (x_pred_normalized-0.75)^2+(y_pred_normalized-0.75)^2)<=0.25) ] )
#--------------
> df.all
x_pred_normalized y_pred_normalized quad circle
1 0.78886879 0.3063979 Third Third
2 0.48122193 0.5440334 Second other
3 0.85496224 0.4849327 Third other
4 0.01457113 0.5116597 Second other
5 0.76936612 0.7424495 Fourth Fourth
6 0.99999000 0.4544564 Third other
7 0.55473184 0.0000000 Third other
8 0.99967092 0.7843946 Fourth other
9 0.72561140 0.3985747 Third Third
10 0.17755530 0.1337408 First First
我看到我使用了 0.25 的圆半径,而你要求的是 0.15。必要的更改应该易于实施。
我正在努力围绕图像中 4 个不同的感兴趣区域设置边界 - 图像和数据采用 0-1 归一化 space,具有四个大小相同的象限。设置方形边界很容易:
df.all$ROI <- ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_left"),
ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_left"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_right"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_right"),
c("other")))))
但是,我想在每个象限 (.25, .25; .25, .75; .75, .25; . 75, .75) 提供相同的输出。
示例数据:
x_pred_normalized <- rnorm(1000, mean=.5, sd=.5)
y_pred_normalized <- rnorm(1000, mean=.5, sd=.5)
df.all <- as.data.frame(cbind(x_pred_normalized, y_pred_normalized))
df.all$ROI_square <- ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_left"),
ifelse(df.all$x_pred_normalised > 0 & df.all$x_pred_normalised <= .5 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_left"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > 0 & df.all$y_pred_normalised <= .5, c("lower_right"),
ifelse(df.all$x_pred_normalised > .5 & df.all$x_pred_normalised <= 1 &
df.all$y_pred_normalised > .5 & df.all$y_pred_normalised <= 1, c("upper_right"),
c("other")))))
期望的输出:
x_pred_normalized y_pred_normalized ROI_square ROI_circle
.99 .99 upper_right other
.51 .51 upper_right other
.25 .25 lower_left lower_left
您的示例不会产生您描述的数据。并且你永远不应该在 data.frame
的调用中使用 cbind
除非有一个数据框对象作为参数之一。这是一个符合您描述的数据框结构(并且足够小,不会在测试时用无用的输出填满您的控制台):
df.all <- data.frame(
x_pred_normalized = pmax( 0, pmin( rnorm(10, mean=.5, sd=.5), 0.99999)),
y_pred_normalized = pmax( 0, pmin( rnorm(10, mean=.5, sd=.5), 0.99999)) )
# all values between 0 and .99999
我发现深度嵌套的 ifelse
结构非常难以调试并且浪费了 space,而使用两列矩阵来 select 字符矩阵中的项目更容易理解.索引数字矩阵中的列是用 findInterval 构造的,因此它将被矢量化并且在时间和 space.
df.all$quad <- matrix(c("First", "Third","Second","Fourth"), ncol=2)[ cbind(
findInterval(df.all$x_pred_normalized,c( 0, .5, 1,Inf) ),
findInterval(df.all$y_pred_normalized,c( 0, .5,1,Inf) ) )]
#--------------
> df.all
x_pred_normalized y_pred_normalized quad
1 0.78886879 0.3063979 Third
2 0.48122193 0.5440334 Second
3 0.85496224 0.4849327 Third
4 0.01457113 0.5116597 Second
5 0.76936612 0.7424495 Fourth
6 0.99999000 0.4544564 Third
7 0.55473184 0.0000000 Third
8 0.99967092 0.7843946 Fourth
9 0.72561140 0.3985747 Third
10 0.17755530 0.1337408 First
对于 circle-containment 列,我将使用逻辑测试乘以索引值,该索引值可用于通过布尔运算从向量中提取值:
dist= function(x,y)
df.all$circle <- with( df.all, c("other", "First", "Second", "Third", "Fourth")[
1 + # value when all subsequent tests are FALSE
1*(sqrt( (x_pred_normalized-0.25)^2+(y_pred_normalized-0.25)^2) <=0.25) +
# above should be should be 1 (TRUE) for lower-rt; else 0
2*(sqrt( (x_pred_normalized-0.25)^2+ (y_pred_normalized-0.75)^2) <=0.25)+
3*(sqrt( (x_pred_normalized-0.75)^2+(y_pred_normalized-0.25)^2) <=0.25)+
4*(sqrt( (x_pred_normalized-0.75)^2+(y_pred_normalized-0.75)^2)<=0.25) ] )
#--------------
> df.all
x_pred_normalized y_pred_normalized quad circle
1 0.78886879 0.3063979 Third Third
2 0.48122193 0.5440334 Second other
3 0.85496224 0.4849327 Third other
4 0.01457113 0.5116597 Second other
5 0.76936612 0.7424495 Fourth Fourth
6 0.99999000 0.4544564 Third other
7 0.55473184 0.0000000 Third other
8 0.99967092 0.7843946 Fourth other
9 0.72561140 0.3985747 Third Third
10 0.17755530 0.1337408 First First
我看到我使用了 0.25 的圆半径,而你要求的是 0.15。必要的更改应该易于实施。