cbind를 사용하여 부분 설정 / 인덱싱을 위해 case_when LHS 변수를 간결하게 재활용하는 방법은 무엇입니까?

알렉스

예제 데이터 :

tmp_df <- 
    data.frame(x_coord = c(3,4), y_coord = c(3, 3))
# x_coord y_coord
# 1       3       3
# 2       4       3

예상대로 작동하는 다음을 고려하십시오.

tmp_df %>%
    mutate(lin_ind = case_when((x_coord < 4 & y_coord < 4) ~ 
                                   x_coord + y_coord,
                               T ~ 0))
# x_coord y_coord lin_ind
# 1       3       3       6
# 2       4       3       0

이제 x_coord매트릭스 y_coord사용 하여 색인화 하겠습니다 3x3.

tmp_df %>%
    mutate(lin_ind = case_when((x_coord < 4 & y_coord < 4) ~ 
                                   matrix(1:9, nrow = 3)[cbind(x_coord, 
                                                               y_coord)],
                               T ~ NA_integer_)
    )
# Error in mutate_impl(.data, dots) : 
#     Evaluation error: subscript out of bounds.

어떤 이유로 cbind부품이 여전히 3보다 큰 열 인덱스를 사용 하므로 실패합니다 .

이것은 tmp_df다음과 같은 특수한 형식 (즉, 두 행)이 있을 때 예상되는 결과를 생성하는 해결 방법입니다 .

tmp_df %>%
    mutate(lin_ind = case_when((x_coord < 4 & y_coord < 4) ~ 
                                   matrix(1:9, nrow = 3)[cbind(x_coord[(x_coord < 4 & y_coord < 4)], 
                                                               y_coord[(x_coord < 4 & y_coord < 4)])],
                               T ~ NA_integer_)
    )
# x_coord y_coord lin_ind
# 1       3       3       9
# 2       4       3      NA

나는 어떻게 case_when작동 하는지에 대해 내가 뭔가를 놓치고 있다고 생각하지 않을 수 없습니다 .

해결 방법 tmp_df은 더 복잡한 경우에도 완전히 실패합니다 .

tmp_df <- 
    data.frame(x_coord = c(3,4, 3), y_coord = c(3, 3, 3))

즉, 3 개의 행만있는 경우 :

> tmp_df %>%
+     mutate(lin_ind = case_when((x_coord < 4 & y_coord < 4) ~ 
+                                    matrix(1:9, nrow = 3)[cbind(x_coord[(x_coord < 4 & y_coord < 4)], 
+                                                                y_coord[(x_coord < 4 & y_coord < 4)])],
+                                T ~ NA_integer_)
+     )
Error in mutate_impl(.data, dots) : 
  Evaluation error: `(x_coord < 4 & y_coord < 4) ~ matrix(1:9, nrow = 3)[cbind(x_coord[(x_coord < 
    4 & y_coord < 4)], y_coord[(x_coord < 4 & y_coord < 4)])]` must be length 3 or one, not 2.

예상 결과를 생성하는 더 복잡한 데이터 프레임에 대한 해결 방법은 다음과 같습니다.

tmp_df %>%
    mutate(lin_ind = case_when((x_coord < 4 & y_coord < 4) ~ 
                                   matrix(1:9, nrow = 3)[cbind(pmin(x_coord, 3), 
                                                               pmin(y_coord, 3))],
                               T ~ NA_integer_)
    )
# x_coord y_coord lin_ind
# 1       3       3       9
# 2       4       3      NA
# 3       3       3       9
유탄 파괴

매트릭스를 추출하기 전에 경계 외부의 인덱스를 대체하는 것은 어떻습니까? 이것은 기본적으로 해결 방법과 동일하지만 case_when()여기 에서는 필요하지 않다고 생각합니다 .


reprex::reprex_info()
#> Created by the reprex package v0.1.1.9000 on 2017-11-18

library(dplyr, warn.conflicts = FALSE)

tmp_df <- 
  data.frame(x_coord = c(3,4, 3), y_coord = c(3, 3, 3))

tmp_df %>%
  mutate(
    mtrx_ind_x = if_else(x_coord < 4, x_coord, NA_real_),
    mtrx_ind_y = if_else(y_coord < 4, y_coord, NA_real_),
    lin_ind = matrix(1:9, nrow = 3)[cbind(mtrx_ind_x, mtrx_ind_y)]
  ) %>%
  select(- starts_with("mtrx_ind"))
#>   x_coord y_coord lin_ind
#> 1       3       3       9
#> 2       4       3      NA
#> 3       3       3       9

당신이 놓친 case_when()것은 인수가 행이 아니라 한 번에 평가된다는 것입니다. 예를 들어, 코드가 우는 소리 않습니다 NOT 붙여 넣기 x[c(2,4,6,8,10)]"px"하지만, 전체 붙여 넣기 x및하여 부분 집합 c(2,4,6,8,10).

x <- 1:10

case_when(
  x %% 2 == 0 ~ paste0(x, "px"),
  TRUE        ~ x
)

내 설명이 의미가 있습니까?

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관