R 当LHS变量用于使用cbind进行子集设置/索引时,如何简洁地循环使用case_?

R 当LHS变量用于使用cbind进行子集设置/索引时,如何简洁地循环使用case_?,r,dplyr,R,Dplyr,示例数据: tmp_df <- data.frame(x_coord = c(3,4), y_coord = c(3, 3)) # x_coord y_coord # 1 3 3 # 2 4 3 由于某种原因,cbind部分仍采用大于3的列索引,因此此操作失败 当tmp_df具有这种特殊形式(即两行)时,这是一种产生预期结果的变通方法: i、 e.只有三行时: > tmp_df %>% + mutate(lin

示例数据:

tmp_df <- 
    data.frame(x_coord = c(3,4), y_coord = c(3, 3))
# x_coord y_coord
# 1       3       3
# 2       4       3
由于某种原因,
cbind
部分仍采用大于3的列索引,因此此操作失败

tmp_df
具有这种特殊形式(即两行)时,这是一种产生预期结果的变通方法:

i、 e.只有三行时:

> 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%>%
+当((x_坐标<4&y_坐标<4)~
+矩阵(1:9,nrow=3)[cbind(x_coord[(x_coord<4&y_coord<4)],
+y_coord[(x_coord<4&y_coord<4)])],
+T~NA_整数)
+     )
mutate_impl(.data,dots)中出错:
计算误差:`(x_坐标<4&y_坐标<4)~矩阵(1:9,nrow=3)[cbind(x_坐标[(x_坐标<
4&y_-coord<4]),y_-coord[(x_-coord<4&y_-coord<4)]]`长度必须为3或1,而不是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
tmp_df%>%
当((x_坐标<4&y_坐标<4)~
矩阵(1:9,nrow=3)[cbind(pmin(x_coord,3),
pmin(y_coord,3))],
T~NA_整数)
)
#x_coord y_coord lin_ind
# 1       3       3       9
#2 4 3 NA
# 3       3       3       9

如果我理解正确,我认为解决这个问题的一个好方法是使用
purr
的映射函数之一。在这里,您可以一起迭代
x_坐标
y_坐标
,并返回带有
map2_int
的整数向量。您可以编写一个简单的匿名函数(这里使用简短的
~
语法完成)来应用于每一组
x\u-coord
y\u-coord


库(dplyr)
图书馆(purrr)
df x_coord y_coord lin_ind
#> 1       3       3       9
#>2 4 3 NA
#> 3       3       3       9

如果我理解正确,我认为解决这个问题的一个好方法是使用
purr
的映射函数之一。在这里,您可以一起迭代
x_坐标
y_坐标
,并返回带有
map2_int
的整数向量。您可以编写一个简单的匿名函数(这里使用简短的
~
语法完成)来应用于每一组
x\u-coord
y\u-coord


库(dplyr)
图书馆(purrr)
df x_coord y_coord lin_ind
#> 1       3       3       9
#>2 4 3 NA
#> 3       3       3       9

在提取矩阵之前,如何替换边界外的索引?虽然这与您的解决方法基本相同,但我认为您不需要在这里使用
case\u when()


reprex::reprex_info()
#>由2017年11月18日的reprex包v0.1.1.9000创建
库(dplyr,warn.conflicts=FALSE)
tmp_df%
变异(
mtrx_ind_x=如果_else(x_coord<4,x_coord,NA_real_),
mtrx_ind_y=如果_else(y_coord<4,y_coord,NA_real_),
林指数=矩阵(1:9,nrow=3)[cbind(mtrx指数x,mtrx指数y)]
) %>%
选择(-以(“mtrx\U ind”)开始)
#>x_coord y_coord lin_ind
#> 1       3       3       9
#>2 4 3 NA
#> 3       3       3       9
我想你所缺少的
case\u when()
是一次计算参数,而不是每行计算参数。例如,下面的代码不会将
x[c(2,4,6,8,10)]
粘贴到
“px”
,而是将整个
x
粘贴到
c(2,4,6,8,10)


x在提取矩阵之前,如何替换边界外的索引?虽然这与您的解决方法基本相同,但我认为您不需要在这里使用
case\u when()


reprex::reprex_info()
#>由2017年11月18日的reprex包v0.1.1.9000创建
库(dplyr,warn.conflicts=FALSE)
tmp_df%
变异(
mtrx_ind_x=如果_else(x_coord<4,x_coord,NA_real_),
mtrx_ind_y=如果_else(y_coord<4,y_coord,NA_real_),
林指数=矩阵(1:9,nrow=3)[cbind(mtrx指数x,mtrx指数y)]
) %>%
选择(-以(“mtrx\U ind”)开始)
#>x_coord y_coord lin_ind
#> 1       3       3       9
#>2 4 3 NA
#> 3       3       3       9
我想你所缺少的
case\u when()
是一次计算参数,而不是每行计算参数。例如,下面的代码不会将
x[c(2,4,6,8,10)]
粘贴到
“px”
,而是将整个
x
粘贴到
c(2,4,6,8,10)


x我很难理解你想要实现什么。您能提供所需输出的示例吗?解决方法是数据帧只有两行的示例(非常简单的示例)。基本上,如果两个索引都有效,则使用
x_-coord
y_-coord
索引到3x3矩阵,否则返回
NA
。我很难理解您想要实现什么。您能提供所需输出的示例吗?解决方法是数据帧只有两行的示例(非常简单的示例)。基本上,如果两个索引都有效,则使用
x_-coord
y_-coord
索引到3x3矩阵,否则返回
NA
。嗯,这是新的和令人兴奋的,但我不确定它是否非常简洁。它也没有解释我在
时对
case\u遗漏了什么。嗯,这是新的和令人兴奋的,但我不确定它是否非常简洁。它也不能解释我在
时缺少了什么。这不是次优吗?(必须评估所有行,然后再评估子集)。啊,不。就性能而言,您的变通版本似乎比我的更快…谢谢。这不是我的错吗
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
tmp_df <- 
    data.frame(x_coord = c(3,4, 3), y_coord = c(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