我试图通过数据库的列逐步迭代一个函数。有哪些选择?我是否仅限于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或类似的简单构造而不是循环来迭代列?
答案 0 :(得分:1)
您可以通过利用列名称的规律性来避免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
答案 1 :(得分:0)
好吧,我现在意识到哈德利已经为最佳解决方案做好了准备;我需要批量处理列转换。我收集具有相同问题(过滤器)的所有列,解决问题,然后以拆分,应用,组合方法将所有帧重新连接在一起。
效率更高:将问题解决为3个表而不是数百个柱状迭代测试每个数据点然后连续响应。
library(magrittr)
matComp %<>% add_rownames
v5Mat <- matComp %>% filter(Level == 5) %>% select(rowname, starts_with("v5"))
v6Mat <- matComp %>% filter(Level == 6) %>% select(rowname, starts_with("v6"))
v7Mat <- matComp %>% filter(Level == 7) %>% select(rowname, starts_with("v7"))
colnames(v5Mat) %<>% gsub("v\\d_", "ref", .)
colnames(v6Mat) %<>% gsub("v\\d_", "ref", .)
colnames(v7Mat) %<>% gsub("v\\d_", "ref", .)
refinedMat <-
Reduce(function(...) merge(..., all=TRUE), list(matComp, v5Mat, v6Mat, v7Mat)) %>%
group_by(rowname) %>%
summarise_each(funs(na.omit))
refinedMat
结果:
Source: local data frame [5 x 10]
rowname refx refy Level v5_x v5_y v6_x v6_y v7_x v7_y
(chr) (chr) (chr) (int) (chr) (chr) (chr) (chr) (chr) (chr)
1 1 x e 5 x e m t k z
2 2 r e 6 z d r e a l
3 3 x z 6 p n x z j x
4 4 u d 7 o g i c u d
5 5 b s 5 b s y u h o