Такое нарушение означает, что в коде есть что-то серьезное, и это ненадежно. Я вижу, что программа может захотеть сохранить данные пользователя таким образом, что, как надеются, не будет писать предыдущие данные, в надежде, что данные пользователя еще не повреждены, но по определению нет стандартного метода борьбы с неопределенным поведением.
Огромное спасибо Парфе за то, что он указал мне правильное направление, особенно с paste0s. Я действительно боролся с тем, что split (), кажется, переименовывает столбцы каждого DF в списке, который нарушает код (заставляет его возвращать NULL).
Это еще одно решение, которое более точно соответствует тому, что мне нужно, чтобы код выполнялся в дикой природе (т.е. не для небольшого набора данных, такого как lalonde). Надеюсь, это пригодится кому-то в будущем.
## packages
library(tidyverse)
library(MatchIt)
##data
data("lalonde")
## randomize the data because lalonde is sorted by treated so the mathcing will fail for some subsets
lalonde2 <- lalonde[sample(nrow(lalonde)),]
##set the size of each subset
n <- 30
nr <- nrow(lalonde2)
### make the subsets
splitter <- split(lalonde2, rep(1:ceiling(nr/n), each=n, length.out=nr))
## write them to file (with replaced names because split() changed them)
for(i in 1:length(splitter)){
names(splitter[[i]]) <- c("treat", "age", "educ", "black", "hispan", "married", "nodegree", "re74", "re75", "re78")
write.csv(splitter[[i]], file = paste0("data_", i, ".csv"))
}
## remove the big one
rm(splitter)
## for loop that runs through each of the saved files from earlier, runs a matching model and matches the data and writes it to a file all in one
require(stringr)
for (i in 1:ceiling(nr/n)){
file<- read.csv(str_c("data_",i,".csv"))
write.csv(match.data(matchit(treat ~ age + educ, method = "nearest", data = file, ratio = 1)), file = paste0("matched_data_", i, ".csv"))
### remove the data after each iteration
rm(file)
}
Рассмотрите возможность инкапсуляции вашего процесса в определенную функцию и используйте функциональные объекты без необходимости именования или удаления из среды. Кроме того, используйте paste
(или его непространственную оболочку, paste0
) на самом столбце, используемом для разбиения. Ниже приведены два альтернативных эквивалентных решения:
Функция
proc_match <- function(sub) {
write.csv(sub, file = paste0("data_", sub$nr[[1]], ".csv"))
match_result <- matchit(am ~ mpg + wt, method = "nearest", data = sub)
matched_data <- match.data(match_result)
write.csv(matched_data, file = paste0("matched_data_", sub$nr[[1]], ".csv"))
}
split
+ lapply
# ADD NEW GROUPING COLUMN
mtcars$grp <- rep(1:ceiling(nr/n), each=n, length.out=nr)
# RUN PROCESS TO RETURN NOTHING
lapply(split(mtcars, mtcars$grp), proc_match)
[ 1111] by
# ADD NEW GROUPING COLUMN
mtcars$grp <- rep(1:ceiling(nr/n), each=n, length.out=nr)
# RUN PROCESS TO RETURN NOTHING
by(mtcars, mtcars$grp, proc_match)