R : 방향 화살표가있는 행렬
Sutton and Barto (2018)에 설명 된 알고리즘을 R로 재현하려고했지만 65 페이지의 저자가 설명한 것처럼 화살표가있는 행렬을 생성 할 수 없었습니다.
![](https://post.nghiatu.com/assets/images/s/RNNJV.png)
이 목적을 위해 "fields"패키지를 사용하려고했지만 성공하지 못했습니다.
Python에서 Shangtong Zhang과 Kenta Shimada가 제안한 솔루션은 화살표 기호를 사용하는 데 의존합니다. ACTIONS_FIGS = [ '←', '↑', '→', '↓'] 그러나 이것은 R에서 잘 작동하지 않습니다.
편집 : 초기 작업을 코딩하고 작업은 다음과 같이 숫자로 업데이트합니다.
library(data.table)
action_random = data.table(cell=c(1:25))
action_random$action_up = action_random$action_right = action_random$action_down = action_random$action_left = rep(1,25)
action_random$proba = rep(1/4,25)
action_random
또한 여기 에 게시 된 코드를 수정하여 간단한 화살표로 간단한 그리드를 그릴 수있었습니다 .
arrows = matrix(c("\U2190","\U2191","\U2192","\U2193"),nrow=2,ncol=2)
grid_arrows = expand.grid(x=1:ncol(arrows),y=1:nrow(arrows))
grid_arrows$val = arrows[as.matrix(grid_arrows[c('y','x')])]
library(ggplot2)
ggplot(grid_arrows, aes(x=x, y=y, label=val)) +
geom_tile(fill='transparent', colour = 'black') +
geom_text(size = 14) +
scale_y_reverse() +
theme_classic() +
theme(axis.text = element_blank(),
panel.grid = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank())
그러나 :
(i) Nice 2에 사용할 수있는 유니 코드는 없습니다.$\pi_\ast$위의
(ii) ... 그래서 저는 테이블 "action_random"의 숫자 값과 화살표가있는 멋진 테이블 사이의 bijection을 코딩하려고하지 않았습니다 ...
문제 (i) 및 (ii) 해결에 도움이되는 모든 힌트를 환영합니다.
답변
다음은 행렬을 재현하는 격자 + 격자 방법입니다.
library(grid)
library(lattice)
grid.newpage()
pushViewport(viewport(width = 0.8, height = 0.8))
grid.rect(width = 1, height = 1)
panel.grid(h = 4, v = 4)
direct = function(xCenter, yCenter, type){
d= 0.05
north = function(xCenter, yCenter){
grid.curve(xCenter, yCenter-d ,xCenter, yCenter+d,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "last",
angle = 30, length = unit(0.2, "cm")))}
west = function(xCenter, yCenter){
grid.curve(xCenter+d, yCenter ,xCenter-d, yCenter,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "last",
angle = 30, length = unit(0.2, "cm")))}
east = function(xCenter, yCenter){
grid.curve(xCenter+d, yCenter ,xCenter-d, yCenter,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "first",
angle = 30, length = unit(0.2, "cm")))}
northeast = function(xCenter, yCenter){
grid.curve(xCenter-d, yCenter+d ,xCenter+d, yCenter-d,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "both",
angle = 30, length = unit(0.2, "cm")))}
northwest = function(xCenter, yCenter){
grid.curve(xCenter-d, yCenter-d ,xCenter+d, yCenter+d,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "both",
angle = 30, length = unit(0.2, "cm")))}
all = function(xCenter, yCenter){
grid.curve(xCenter+d, yCenter ,xCenter-d, yCenter,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "both",
angle = 30, length = unit(0.2, "cm")))
grid.curve(xCenter, yCenter-d ,xCenter, yCenter+d,
ncp = 1, angle = 90, gp=gpar(lwd=1, fill="black"),
inflect = FALSE, shape = 0,
arrow = arrow(type="closed", ends = "both",
angle = 30, length = unit(0.2, "cm")))}
switch(type,
'n' = north(xCenter, yCenter),
'e' = east(xCenter, yCenter),
'w' = west(xCenter, yCenter),
'nw'= northwest(xCenter, yCenter),
'ne' = northeast(xCenter, yCenter),
'all' = all(xCenter, yCenter)
)
}
x = seq(0.1, 0.9, by = 0.2)
y = x
centers = expand.grid(x0 = x, y0 = y)
row1 = row2 = row3 = c('ne','n', rep('nw',3))
row4 = c('ne','n','nw','w','w')
row5 = c('e','all','w','all','w')
dir = c(row1,row2,row3,row4,row5)
df = data.frame(centers, dir)
for (k in 1:nrow(df)) direct(df$x0[k], df$y0[k], df$dir[k])
grid.text(bquote(~pi["*"]), y = -0.05)
![](https://post.nghiatu.com/assets/images/s/YwVrX.png)
패키지를 사용하면 emojifont
더 많은 유니 코드 옵션을 얻을 수 있습니다. ggplot에서 family='EmojiOne'
. 다음은 유니 코드를 사용한 예입니다.
패키지 이모티콘 글꼴에 대한 자세한 내용은 여기
편집 : 4 방향 화살표 해킹 :
가장 예쁘거나 우아한 솔루션은 아니지만 패키지 magick
를 사용하여 ggplot을 오버레이하여 방향 화살표를 얻을 수 있습니다. 왼쪽-오른쪽 화살표 ( U+2194
)와 위쪽 화살표 ( )가있는 두 개의 플롯 레이어를 U+2195
만든 다음 병합합니다 (코드를 좀 더 우아하게 만들어 준 @ Billy34에게 감사드립니다).
library(data.table)
library(magick)
library(ggplot2)
library(emojifont)
#layer 1
arrows1 = matrix(c("\U21B4","\U2195","\U2192","\U2193"),nrow=2,ncol=2)
grid_arrows1 = expand.grid(x=1:ncol(arrows1),y=1:nrow(arrows1))
grid_arrows1$val = arrows1[as.matrix(grid_arrows1[c('y','x')])] #layer 2 arrows2 = matrix(c("\U21B4","\U2194","\U2192","\U2193"),nrow=2,ncol=2) grid_arrows2 = expand.grid(x1=1:ncol(arrows2),y1=1:nrow(arrows2)) grid_arrows2$val = arrows2[as.matrix(grid_arrows2[c('y1','x1')])]
ggplot(grid_arrows1, aes(x=x, y=y, label=val),family='EmojiOne') +
geom_tile(fill='NA', colour = 'black') +
geom_text(size = 18) +
geom_text(grid_arrows2,mapping = aes(x=x1, y=y1, label=val),size = 18) +
scale_y_reverse() +
theme_classic() +
theme(
panel.background = element_rect(fill = "transparent"), # bg of the panel
plot.background = element_rect(fill = "transparent", color = NA), # bg of the plot
axis.text = element_blank(),
panel.grid = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank()# get rid of legend panel bg
)
#save plot as image
ggsave(filename = 'plot1.png', device = 'png', bg = 'transparent')
# read images with package magick
plot1 <- image_read('plot1.png')
image_mosaic(plot1)
![](https://post.nghiatu.com/assets/images/s/nUlOX.png)
최신 정보:
이전 코드처럼 우아하지 않지만 찾고있는 것에 더 가깝습니다.
특정 유니 코드는 특정 글꼴에서만 작동하므로 첫 번째 단계는 찾고있는 유니 코드에 적합한 글꼴을 찾는 것입니다. 다음은 아래 예에서 사용 된 왼쪽 화살표 유형에 대한 글꼴 지원 의 예입니다 .
물론 삶이 그렇게 쉽지 않기 때문에 목록에있는 글꼴 중 어느 것도 표준이 아닙니다. 따라서 다음 단계는 글꼴을 설치하는 것입니다. 여기서 다운로드 한 Symbola 글꼴을 사용 했습니다 . 프로젝트를 사용하는 경우 글꼴 파일을 R 디렉토리 또는 프로젝트 폴더에 복사하십시오.
그런 다음 라이브러리 showtext를 사용하십시오 . 이 패키지를 사용하면 그래픽에서 시스템 글꼴을 사용할 수 있습니다 (패키지 필요 sysfonts
). OS에서 글꼴이 표준 이라면 systemfonts 패키지를 살펴볼 것을 권장합니다 .
내 예제에서 나는 화살표를 사용 \U1F800
하고 \U1F801
그 다음, 내 앞의 예처럼, 내가 그들을 중복, ( PS : 당신이 바보짓해야 할 수도 있습니다 nudge_y
과 nudge_x
에서 geom_text
그들을 제대로 정렬하려면) :
library(data.table)
library(magick)
library(ggplot2)
library(showtext)
#layer 1, upwards arrow
arrows1 = matrix(c("", "\U1F801", "\U1F801", ""),
nrow = 2,
ncol = 2)
grid_arrows1 = expand.grid(x = 1:ncol(arrows1), y = 1:nrow(arrows1))
grid_arrows1$val = arrows1[as.matrix(grid_arrows1[c('y', 'x')])] #layer 2 , leftwards arrow arrows2 = matrix(c("", "\U1F800", "\U1F800", ""), nrow = 2, ncol = 2) grid_arrows2 = expand.grid(x1 = 1:ncol(arrows2), y1 = 1:nrow(arrows2)) grid_arrows2$val = arrows2[as.matrix(grid_arrows2[c('y1', 'x1')])]
#layer 3 , upwards arrow
arrows3 = matrix(c("\U1F801", "", "", "\U1F801"),
nrow = 2,
ncol = 2)
grid_arrows3 = expand.grid(x2 = 1:ncol(arrows3), y2 = 1:nrow(arrows3))
grid_arrows3$val = arrows3[as.matrix(grid_arrows3[c('y2', 'x2')])] #layer 4 , leftwards arrow arrows4 = matrix(c("\U1F800", "", "", "\U1F800"), nrow = 2, ncol = 2) grid_arrows4 = expand.grid(x3 = 1:ncol(arrows4), y3 = 1:nrow(arrows4)) grid_arrows4$val = arrows4[as.matrix(grid_arrows4[c('y3', 'x3')])]
#use function font_add from lybrary showtext
font_add("Symbola", regular = "Symbola_hint.ttf")
# Take a look at the function showtext_auto() as well
ggplot(grid_arrows1,
aes(x = x, y = y, label = val),
family = 'Symbola',
size = 18) +
geom_tile(fill = 'NA', colour = 'black') +
geom_text(
grid_arrows1,
mapping = aes(x = x, y = y, label = val),
family = 'Symbola',
size = 18
) +
geom_text(
grid_arrows2,
mapping = aes(x = x1, y = y1, label = val),
family = 'Symbola',
size = 18,
nudge_x = -0.01
) +
geom_text(
grid_arrows1,
mapping = aes(x = x, y = y, label = val),
family = 'Symbola',
size = 18,
angle = 180
) +
geom_text(
grid_arrows2,
mapping = aes(x = x1, y = y1, label = val),
family = 'Symbola',
size = 18,
angle = 180,
nudge_x = 0.01,
nudge_y = 0.007
) +
geom_text(
grid_arrows3,
mapping = aes(x = x2, y = y2, label = val),
family = 'Symbola',
size = 17,
nudge_y = 0.03
) +
geom_text(
grid_arrows4,
mapping = aes(x = x3, y = y3, label = val),
family = 'Symbola',
size = 17,
nudge_x = -0.021,
nudge_y = -0.01
) +
scale_y_reverse() +
theme_classic() +
theme(
panel.background = element_rect(fill = "transparent"),
# bg of the panel
plot.background = element_rect(fill = "transparent", color = NA),
# bg of the plot
axis.text = element_blank(),
panel.grid = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank()# get rid of legend panel bg
)
#save plot as image
ggsave(filename = 'plot.png',
device = 'png',
bg = 'transparent')
# read images with package magick
image_read('plot.png')
내가 얻은 결과는 다음과 같습니다.
![](https://post.nghiatu.com/assets/images/s/sGbe8.png)
나는 이것이 지금까지 본 것 중 가장 예쁜 코드라고 말할 수는 없지만, 그것이 얻는 것만 큼 해킹이지만 도움이 될 수 있습니다! (이 작업을 수행하는 데 내가 인정하고 싶은 것보다 더 많은 시간이 걸렸습니다!)