我正在尝试通过数据库的列逐步迭代一个函数。为此有哪些可用选项?我是否仅限于 for 循环,或者我可以使用 dplyr 方法或类似直观的代码结构吗?
基本上我有一个比下面构造的矩阵大得多的矩阵,但具有相同的一般结构。第一列解释了选择哪个版本作为优化的数据集合,然后是包含这三个版本的所有数据。
library(dplyr)
# Function: creates a matrix of random strings, v = versionNumber
matADv.maker <- function (v){
matADv <- data.frame(matrix(sample(letters[1:26], 10), nrow = 5))
colnames(matADv) <- paste0("v", v, "_", letters[24:25])
return(matADv)
}
set.seed(1)
lvl <- data.frame(c(as.integer(runif(5, 5, 8))))
colnames(lvl) <- "Level"
matADv5 <- matADv.maker(5)
matADv6 <- matADv.maker(6)
matADv7 <- matADv.maker(7)
matComp <- bind_cols(lvl, matADv5, matADv6, matADv7)
matComp
Source: local data frame [5 x 8]
rowname Level v5_x v5_y v6_x v6_y v7_x v7_y (chr) (int) (chr) (chr) (chr) (chr) (chr) (chr) 1 1 5 x e m t k z 2 2 6 z d r e a l 3 3 6 p n x z j x 4 4 7 o g i c u d 5 5 5 b s y u h o
我想知道是否有一些简单的方法可以沿着数据框穿梭函数。
本质上,我怎样才能使用 dplyr 或比 for 循环更简单的类似结构来遍历列?
最佳答案
您可以通过利用列名的规律性来避免 ifelse
和循环。这是一个基本的 R 解决方案:
对于 matComp
的每一行,您想要找到其列名包含给定“后缀”(x 或 y)的正确 Level
值的列,并且将该值分配给新的 refdat
列。您可以使用 match
函数执行此操作。
在下面的代码中,我们使用apply
遍历matComp
的每一行。在每一行中,我们使用 match
找到所需列的索引,以便我们可以为 refdat
返回正确的值。 sapply
迭代两个后缀,cbind
将两个新列添加到 matcomp
。
matComp = cbind(matComp,
sapply(paste0("refdat_",c("x","y")), function(var) {
suffix = substr(var, nchar(var), nchar(var))
apply(matComp, 1, function(vec) {
vec[match(paste0("v", vec["Level"], "_", suffix), names(vec))]
})
}), stringsAsFactors=FALSE)
Level v5_x v5_y v6_x v6_y v7_x v7_y refdat_x refdat_y 1 5 x e m t k z x e 2 6 z d r e a l r e 3 6 p n x z j x x z 4 7 o g i c u d u d 5 5 b s y u h o b s
关于r - 遍历 dplyr 中的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37848501/