首先,是的,我已经研究了这个问题,是的,我已经看到了几个可以解决我问题的答案,但是我似乎无法将其应用于我的情况,所以我直接去找源头,希望有人能通过我的想法得到这个概念。我的数据显示出厚厚的头骨。这显然是一个小得多的例子。我试图过滤我们的行,其中包含来自Code_任一列中的向量的值,并将它们保存为每次迭代的数据框。现在,此代码在每次遍历中都添加了一个突变列,以显示代码向量中的哪个值已用于该过滤器。当然,这会导致很多重复,而且我仍然必须将输出分开,以将每次迭代放入自己的单独df中。
transaction <- c(1,2,3,4,5)
Code_1 <- c("QD","QK","QI","QE","QH")
Code_2 <- c("QE","QB","SA","QG","QC")
Code_3 <- c("QG","QH","DI","QK","QI")
Code_4 <- c("QK","QC","QD","QB","SA")
df <- data.frame(transaction, Code_1, Code_2, Code_3, Code_4)
codes <- c("QD","QH","SA")
test <- data.frame(NULL)
for(i in codes){
tmp <- df %>% filter(Code_1 == i | Code_2 == i | Code_3 == i| Code_4 == i) %>% mutate(interation =
i)
test <- rbind(test, tmp)
}
我得到一个输出,该输出捕获了我想要的所有行,但是我仍然必须根据变异列“ iteration”将它们操纵为单独的dfs。有什么方法可以丢失变异列并将每个迭代另存为df?它循环。我已经尝试了几个示例,并尝试了几个应用场景,但这是我唯一能够开始工作的东西。
很抱歉与输出混淆
在理想世界中,我希望每次迭代都输出唯一的tibble / df。我想要一个输出,就好像我刚刚运行了这样的东西,但是在数百个代码上运行了一千次。我不要清单。我想要唯一的个人输出。
QD <- df %>% filter(Code_1 == "QD" | Code_2 == "QD" | Code_3 == "QD"|
Code_4 == "QD")
QH <- df %>% filter(Code_1 == "QH" | Code_2 == "QH" | Code_3 == "QH"|
Code_4 == "QH")
SA <- df %>% filter(Code_1 == "SA" | Code_2 == "SA" | Code_3 == "SA"|
Code_4 == "SA")
答案 0 :(得分:3)
逐行增长帧在逻辑上是合理的,但可以可怕地缩放:添加每行,整个帧就被复制到内存中。这意味着当您有100行时,要添加1行,您的内存中前100行将为两次。
解决方法是通常将行保存在list
中,然后手动一步将它们合并。
out <- list()
for(i in codes){
tmp <- df %>% filter(Code_1 == i | Code_2 == i | Code_3 == i| Code_4 == i) %>% mutate(interation = i)
out <- c(out, list(tmp))
}
out
# [[1]]
# transaction Code_1 Code_2 Code_3 Code_4 interation
# 1 1 QD QE QG QK QD
# 2 3 QI SA DI QD QD
# [[2]]
# transaction Code_1 Code_2 Code_3 Code_4 interation
# 1 2 QK QB QH QC QH
# 2 5 QH QC QI SA QH
# [[3]]
# transaction Code_1 Code_2 Code_3 Code_4 interation
# 1 3 QI SA DI QD SA
# 2 5 QH QC QI SA SA
do.call(rbind, out)
# transaction Code_1 Code_2 Code_3 Code_4 interation
# 1 1 QD QE QG QK QD
# 2 3 QI SA DI QD QD
# 3 2 QK QB QH QC QH
# 4 5 QH QC QI SA QH
# 5 3 QI SA DI QD SA
# 6 5 QH QC QI SA SA
我应该补充一点,我保留了for
循环,使其与您的起始代码相似; Rui提出的使用lapply
的建议是朝“更好”方向迈出的一步。
答案 1 :(得分:3)
这是一种lapply
解决方案,不需要tmp
data.frame。
codes <- c("QD","QH","SA")
test <- lapply(codes, function(i){
df %>%
filter(Code_1 == i | Code_2 == i | Code_3 == i| Code_4 == i) %>%
mutate(interation = i)
})
test
test <- do.call(rbind, test)
test
# transaction Code_1 Code_2 Code_3 Code_4 interation
#1 1 QD QE QG QK QD
#2 3 QI SA DI QD QD
#3 2 QK QB QH QC QH
#4 5 QH QC QI SA QH
#5 3 QI SA DI QD SA
#6 5 QH QC QI SA SA
答案 2 :(得分:1)
我们可以使用rowSums
library(dplyr)
library(purrr)
map(codes, ~
df %>%
filter(rowSums(select(.,
starts_with('Code')) == .x) > 0) %>%
mutate(interaction = .x)
)
#[[1]]
# transaction Code_1 Code_2 Code_3 Code_4 interaction
#1 1 QD QE QG QK QD
#2 3 QI SA DI QD QD
#[[2]]
# transaction Code_1 Code_2 Code_3 Code_4 interaction
#1 2 QK QB QH QC QH
#2 5 QH QC QI SA QH
#[[3]]
# transaction Code_1 Code_2 Code_3 Code_4 interaction
#1 3 QI SA DI QD SA
#2 5 QH QC QI SA SA
答案 3 :(得分:0)
一个tidyverse
解决方案。我们将命名输入向量,以使输出test
实际上是根据需要命名的小标题列表
codes <- c("QD","QH","SA")
names(codes) <- codes
library(dplyr)
library(purrr)
test <- purrr::map(codes, function(i){
df %>%
rowwise() %>%
filter(i %in% c_across(Code_1:Code_4)) %>%
mutate(interation = i) %>%
ungroup
})
# test has everything but they are all named so ...
test$QD
#> # A tibble: 2 x 6
#> transaction Code_1 Code_2 Code_3 Code_4 interation
#> <dbl> <chr> <chr> <chr> <chr> <chr>
#> 1 1 QD QE QG QK QD
#> 2 3 QI SA DI QD QD