Haven: read_dta error() «Не удалось разобрать /Users/folder/my_data.dta: невозможно выделить память»

У меня есть относительно большой файл .dta с 1280000 наблюдений, который отлично работает в Stata, но у меня возникают проблемы с его импортом в R. Данные были созданы с помощью Stata 15, данные содержат переменные strL или str#, #>244 и не могут быть сохранены в формате Stata 12.

Я пытаюсь использовать пакет haven для импорта сохраненных данных с помощью read_dta(), но выдает следующее сообщение об ошибке: "Failed to parse /Users/folder/my_data.dta: Unable to allocate memory." Кто-нибудь знает, что может быть причиной этой проблемы и как ее преодолеть, чтобы иметь возможность импортировать данные в R?

Я пытался решить эту проблему несколькими способами, но ни одна из моих попыток не работает.

  1. Сначала я попытался увеличить размер памяти моей среды r с помощью Sys.setenv('R_MAX_VSIZE'=32000000000), но консоль сообщает о той же ошибке, когда я пытаюсь импортировать данные. Проблема, похоже, не связана с размером моей памяти в R.

  2. Я попытался сохранить данные в формате Stata 13, используя saveold my_data13, version(13) в Stata, но попытка импортировать их в R с помощью haven по-прежнему выдает то же сообщение об ошибке.

  3. Я пытался использовать функцию readstata13 read.dta13(my_data13), но это регулярно приводило к сбою R.

Странно то, что я могу правильно открыть данные в Stata, просто дважды щелкнув по ним.

Есть ли у кого-нибудь предложения о том, как решить эту проблему? Приветствуется любое понимание а) значения сообщения об ошибке и способов его устранения; 2) альтернативных пакетов, способных работать с файлами stata15; в) подхода к открытию данных в R.

Заранее большое спасибо за вашу помощь

С наилучшими пожеланиями

Если какой-либо обходной путь не сработает, как насчет экспорта в файл другого типа, например csv, в Stata, а затем импорта в R с использованием файла csv?

Wouter 15.12.2020 13:09

Я согласен с @Wouter, что вы можете экспортировать файл во что-то вроде CSV, хотя я могу предвидеть некоторые трудности, учитывая структуру URL, с которой вы работаете. Другой подход — попытаться импортировать файл .dta в Python , а затем из Python экспортировать его в R.

Álvaro A. Gutiérrez-Vargas 15.12.2020 19:00

Уважаемый Альваро, большое спасибо за ваше понимание, к сожалению, как вы и предсказываете, у меня проблемы с экспортом в CSV-файлы, так как длинные строки неправильно хранятся в CSV-файле, и его повторное открытие создает дополнительные проблемы. попробую вариант с питоном, но жаль, что нет прямого способа сделать это в R

Alex 15.12.2020 19:11

Итак, я смог получить доступ к необработанному CSV-файлу, я импортировал его в R, а затем попытался сохранить его с помощью write_dta(aparm_f,"data.dta") и получил следующую ошибку Writing failure: A provided string value was longer than the available storage size of the specified column. могут ли быть связаны две проблемы?

Alex 15.12.2020 19:25

@Alex, к счастью, я увидел твой комментарий (не забывай отмечать людей при комментировании). По моему мнению, и я предполагаю здесь, проблемы кажутся связанными. Теперь, с этой информацией, я немного запутался в вашей конечной цели. Вы хотите работать с данными в Stata или R?

Álvaro A. Gutiérrez-Vargas 15.12.2020 19:39

Уважаемый @ÁlvaroA.GutiérrezVargas, спасибо за ваш ответ. Моя цель — работать с обоими, я предпочитаю использовать R, а мой коллега предпочитает Stata. И есть определенные вещи, которые мы предпочитаем делать с одним R, а другие со Stata. Суть в том, что я хотел бы иметь возможность легко переходить из одной программы в другую. но мы сталкиваемся с невозможностью плавного перехода от одной программы к другой.

Alex 15.12.2020 19:44

Уважаемый @Alex, я вижу, что проблему решить сложнее, чем кажется, в частности, из-за расширения URL. Предполагая, что у вас есть доступ к Stata версии 15 или более поздней (из-за длины строк, которые можно сохранить), я бы обработал все, что вы хотите сделать, используя либо R, либо Stata, и сохранил вывод в CSV. Позже вы можете продолжить с сохраненного файла CSV и перейти к следующему анализу в любом программном обеспечении, которое вам нравится, не ограничиваясь файлами .dta o .rds.

Álvaro A. Gutiérrez-Vargas 15.12.2020 19:57

Уважаемый @ÁlvaroA.GutiérrezVargas, большое спасибо за ваш ответ. На самом деле я боюсь, что проблема связана с тем, что две мои строки символов содержат до 4200 символов. Использование cvs, вероятно, является лучшим вариантом, если никто не может дать представление о том, как импортировать такие .dta файлы с длинными строками в R.

Alex 15.12.2020 20:11

В случае, если кому-то интересно, я смог преодолеть проблему в stata. Проблема заключалась в переменных strL. Я создал цикл для преобразования всех переменных strL в переменные str#, а затем смог сохранить данные в Stata и регулярно импортировать их в R с помощью haven. вот цикл для Stata: foreach var of varlist var1 var2 { generate str 'var'_str = 'var' replace 'var' = "" compress 'var' replace 'var' = 'var'_str drop 'var'_str describe 'var' }

Alex 15.12.2020 23:41

@ Алекс, я завершил всю нашу дискуссию ответом на твой вопрос, главным образом потому, что мне было любопытно узнать всю эту проблему. Если у вас есть какие-либо вопросы или комментарии, я был бы более чем счастлив прочитать вас.

Álvaro A. Gutiérrez-Vargas 16.12.2020 15:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
10
2 838
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я просто хочу подвести итог всему, что упоминалось в комментариях.

Из официальной документации Stata у нас есть следующее:

Переменные strL могут иметь длину от 0 до 2 миллиардов байт. Переменные strL не должны быть длиннее 2045 байт. Переменные str# могут хранить строки размером до 2045 байт, поэтому strL и str# перекрываются. Это перекрытие сравнимо с перекрытием числовых типов int и float. Любое число, которое может быть сохранено как целое, может быть сохранено как число с плавающей запятой. Точно так же любая строка, которая может быть сохранена как str#, может быть сохранена как strL. Обратное неверно. Кроме того, переменные strL могут содержать двоичные строки, тогда как переменные str# могут содержать только текстовые строки. Таким образом, аналогия между str#/strL и int/float является точной. Будут случаи, когда вы захотите использовать переменные strL вместо переменных str#, точно так же, как бывают случаи, когда вы захотите использовать переменные с плавающей запятой вместо переменных int.

Приведенная выше информация заставляет меня сделать два вывода, прежде чем я попытаюсь воспроизвести вашу проблему.

  1. В вашем случае использование strL не требовалось.

  2. Использование strL было источником вашей проблемы, что, вероятно, привело к некоторым проблемам совместимости с библиотекой haven.

Однако после попытки воспроизвести то, что вы описали, я пришел к другому выводу.


Пожалуйста, внимательно рассмотрите следующий код, который эмулирует вашу проблему.

version 16
clear all 
set obs 1
*4200 character string generated here: http://www.unit-conversion.info/texttools/random-string-generator/
gen strL str_var_in_strL = "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"

describe

Contains data
  obs:             1                          
 vars:             1                          
------------------------------------------------------------------------------------
              storage   display    value
variable name   type    format     label      variable label
------------------------------------------------------------------------------------
str_var_in_strL strL    %9s                   
------------------------------------------------------------------------------------

save "route\all_in_strL" , replace

После этого я применил вашу модификацию к сгенерированным данным.

gen var1 = str_var_in_strL

foreach var of varlist var1 {
     generate str `var'_str = `var' 
     replace `var' = "" 
     compress `var' 
     replace `var' = `var'_str  
     drop `var'_str  
     describe `var' 
}

  obs:             1                          
 vars:             2                          16 Dec 2020 12:07
------------------------------------------------------------------------------------
              storage   display    value
variable name   type    format     label      variable label
------------------------------------------------------------------------------------
str_var_in_strL strL    %9s                   
var1            strL    %9s                   
------------------------------------------------------------------------------------

save "route\edited_strL" , replace 

Как ни странно, я смог импортировать оба файла в R, используя библиотеку haven со следующим кодом.

library(haven)
file <- "route_to_first_file/all_in_strL.dta"
# Import first file into R.

dta_in_R <- read_dta(
                    file,
                    encoding = NULL,
                    col_select = NULL,
                    skip = 0,
                    n_max = Inf,
                    .name_repair = "unique")



# Import edited file using your loop method into R.
file <- "route_to_edited_file/edited_strL.dta"

edited_dta_in_R<- read_dta(
                          file,
                          encoding = NULL,
                          col_select = NULL,
                          skip = 0,
                          n_max = Inf,
                          .name_repair = "unique")


Единственными отличиями здесь могут быть:

  1. Размер набора данных (в моем случае всего одно наблюдение).
  2. Возможно, вы используете более раннюю версию Stata (я использую Stata 16).

Наконец, я думаю, что источником проблемы был не strL тип данных, а память, доступная на вашем компьютере, которая, вероятно, была решена вашим compress шагом в цикле for, который вы описали.


PS: Все запускалось на Win10. R версия 4.0.3 (2020-10-10) и haven_2.3.1

Хорошая работа. Пожалуйста, убедитесь, что мои правки не изменили вашего предполагаемого значения.

Nick Cox 16.12.2020 13:11

Смысл остался прежним после издания. Спасибо за исправления @NickCox.

Álvaro A. Gutiérrez-Vargas 16.12.2020 14:36

FWIW, у меня была эта проблема, и она была исправлена ​​запуском compress перед сохранением в stata. Кое-что о наличии данных strL. Это не проблема системной памяти.

Kyouma 02.08.2021 14:29

Другие вопросы по теме