非常简单的问题。
有没有一种方法可以避免在
apply()
中进行简化?
我需要这样做,因为我有一个apply
,它有时可以简化(并且可以做到),有时却不能,从而根据输入创建不同的数据结构,因此我想完全避免使用它。 / p>
我需要类似于SIMPLIFY = FALSE
中的mapply()
的东西,或者需要一种像vapply()
中那样控制输出的机制。
简单的可复制示例:
mimat <- matrix(c(1,2,3,4,5,6), nrow = 2)
mimat2 <- matrix(c(3,2,3,4,5,6), nrow = 2)
apply(mimat, MARGIN = 2, function(x) {
if (is.element(el = 1, x)) return(c(0,1))
else return(c(1,2,3))
})
如果将apply()
应用于mimat
,则输出列表,而如果将mimat2
应用于''
,则输出矩阵。
答案 0 :(得分:0)
从 2021-03-06 开始,R-devel 为 simplify
提供了 apply()
参数。
在 R 版本发布之前,最好的选择可能是
lapply(seq_len(dim(minat)[2]), YourFunction)
答案 1 :(得分:0)
我认为 purrr
包中的函数可能更适合您的目的,因为输出几乎是事先已知的。如果他们无法将输出与他们应该返回的数据结构匹配,他们就会抛出错误(或者像文档所说的那样尝试死亡)。
例如 map
函数总是返回一个列表,而它的变体 map_dbl
、map_lgl
等都返回一个指定类型的向量。
在这个系列中还有一个函数叫做 modify
,它保留了输入数据的结构(行号和列号)并且不改变数据结构,但是文档中说>
<块引用>
由于转换可以改变输入的结构;它是 您有责任确保转换产生有效的 输出。例如,如果您要修改数据框,则 .f 必须 保留输入的长度。
在您将匿名函数应用于 mimat
的第一个示例中,结果具有不同的长度,因此无法返回矩阵或数据框,因为我可以尝试使用 map
来获得相同的结果,而 modify
未能保留输入的数据结构:
library(purrr)
map(as.data.frame(mimat), function(x) {
if (is.element(el = 1, x)) return(c(0,1))
else return(c(1,2,3))
})
$V1
[1] 0 1
$V2
[1] 1 2 3
$V3
[1] 1 2 3
modify(as.data.frame(mimat), function(x) {
if (is.element(el = 1, x)) return(c(0,1))
else return(c(1,2,3))
})
> Error in `[[<-.data.frame`(`*tmp*`, i, value = c(1, 2, 3)) :
> replacement has 3 rows, data has 2
但是在您的第二个矩阵 mimat2
的情况下,函数的输出具有相等长度的行,因此可以使用名为 map
的 map_dfc
变体来 col 绑定输出。由于 modify
再次失败导致输出数据结构与输出不同:
map_dfc(as.data.frame(mimat2), function(x) {
if (is.element(el = 1, x)) return(c(0,1))
else return(c(1,2,3))
})
# A tibble: 3 x 3
V1 V2 V3
<dbl> <dbl> <dbl>
1 1 1 1
2 2 2 2
3 3 3 3
modify(as.data.frame(mimat2), function(x) {
if (is.element(el = 1, x)) return(c(0,1))
else return(c(1,2,3))
})
Error in `[[<-.data.frame`(`*tmp*`, i, value = c(1, 2, 3)) :
replacement has 3 rows, data has 2
我必须将它们转换为数据框,否则它们将被视为向量,并且该函数应用于每个元素而不仅仅是列。 这个简短的解释可能无法让您了解您想要的内容,但我希望它只是介绍一些其他具有固定输出的功能。 简而言之,它只能归结为您在数据结构上应用的功能,该功能必须以一种可以保留数据结构的方式转换数据。