Как я могу создать несколько объектов в R и сохранить их в отдельных файлах CSV? - PullRequest
0 голосов
/ 02 марта 2019

Я исследовал этот вопрос сегодня, и то, что я нашел, говорит мне, как перебирать существующие CSV-файлы в каталоге и что-то делать, но я не могу найти решение моей конкретной проблемы

Что я хочу сделать:

1) разделить мой фрейм данных на несколько частей

2) для каждой части я хочу записать его как CSV, сохранив его имя как data_iгде «i» - это индекс цикла

3) для каждой порции запускается соответствующая модель из MatchIt

4) для каждой порции и для соответствующей модели получают совпавшие данные

5) сохранить сопоставленные данные как объект, называемый matched_data_i.csv, снова "i" - индекс цикла

6) завершить цикл, удалив data_i и подходящую модель

вот некоторыекод, который не работает, но показывает, где я хочу быть:

library(tidyverse)
library(MatchIt)

data("mtcars")
View(mtcars)

n <- 10
nr <- nrow(mtcars)

splitter <- split(mtcars, rep(1:ceiling(nr/n), each=n, length.out=nr))

for(i in splitter){
  write.csv(splitter[i], file = paste0(data_i)) ## this is a part I need help on, how do i name each CSV according to its loop index?

  ### how do i name each object  mod_match_[i] where i is the index of the loop?

  mod_match_[i] = matchit(am ~ mpg + wt, method = "nearest", data = as.data.frame(splitter[i])) ##I think it is a data frame anyway but doesn't hurt to be sure since matchit falls over when exposed to tibbles (from experience)

  matched_data_[i] = match.data(mod_match_[i]) ### again i don't know how to make the name of this object change depending on which "i" we're up to

  write.csv(matched_data_[i], file = "matched_data_[i].csv") ## how can i save each one as a separate CSV with a name referring to the index?

  ## i want to remove the objects before repeating the loop

  rm(mod_match_[i])
  rm(matched_data_[i])

}

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Огромное спасибо Парфе за то, что он указал мне правильное направление, особенно с 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)

}
0 голосов
/ 02 марта 2019

Рассмотрите возможность инкапсуляции вашего процесса в определенную функцию и используйте функциональные объекты без необходимости именования или удаления из среды.Кроме того, используйте 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)

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...