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