很简单的问题。
在
apply()中有避免简化的方法吗?
我需要这样做,因为我有一个apply,它有时可以简化(也可以简化),有时不能简化,从而根据输入创建不同的数据结构,所以我想完全避免它。
我要么需要类似于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,则输出矩阵。
发布于 2021-04-14 09:45:43
R4.1.0向simplify上的apply()添加了一个2021-03-06参数。
对于旧版本的R,最好的选择可能是
lapply(seq_len(dim(minat)[2]), YourFunction)发布于 2021-04-14 11:47:09
出于您的目的,我认为来自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_dfc的map变量来绑定输出。由于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我必须将它们转换为数据帧,否则它们将被视为向量,函数将应用于每个元素,而不仅仅是列。这个简短的解释可能不会让你理解你想要的东西,但我希望它只是一个介绍一些固定输出的其他功能。简而言之,它只能归结为应用在数据结构上的函数,该函数必须以一种能够保留数据结构的方式转换数据。
https://stackoverflow.com/questions/53481834
复制相似问题