У меня есть относительно большой файл .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?
Я пытался решить эту проблему несколькими способами, но ни одна из моих попыток не работает.
Сначала я попытался увеличить размер памяти моей среды r с помощью Sys.setenv('R_MAX_VSIZE'=32000000000)
, но консоль сообщает о той же ошибке, когда я пытаюсь импортировать данные. Проблема, похоже, не связана с размером моей памяти в R.
Я попытался сохранить данные в формате Stata 13, используя saveold my_data13, version(13)
в Stata, но попытка импортировать их в R с помощью haven
по-прежнему выдает то же сообщение об ошибке.
Я пытался использовать функцию readstata13 read.dta13(my_data13)
, но это регулярно приводило к сбою R.
Странно то, что я могу правильно открыть данные в Stata, просто дважды щелкнув по ним.
Есть ли у кого-нибудь предложения о том, как решить эту проблему? Приветствуется любое понимание а) значения сообщения об ошибке и способов его устранения; 2) альтернативных пакетов, способных работать с файлами stata15; в) подхода к открытию данных в R.
Заранее большое спасибо за вашу помощь
С наилучшими пожеланиями
Я согласен с @Wouter, что вы можете экспортировать файл во что-то вроде CSV, хотя я могу предвидеть некоторые трудности, учитывая структуру URL, с которой вы работаете. Другой подход — попытаться импортировать файл .dta в Python , а затем из Python экспортировать его в R.
Уважаемый Альваро, большое спасибо за ваше понимание, к сожалению, как вы и предсказываете, у меня проблемы с экспортом в CSV-файлы, так как длинные строки неправильно хранятся в CSV-файле, и его повторное открытие создает дополнительные проблемы. попробую вариант с питоном, но жаль, что нет прямого способа сделать это в R
Итак, я смог получить доступ к необработанному 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, к счастью, я увидел твой комментарий (не забывай отмечать людей при комментировании). По моему мнению, и я предполагаю здесь, проблемы кажутся связанными. Теперь, с этой информацией, я немного запутался в вашей конечной цели. Вы хотите работать с данными в Stata или R?
Уважаемый @ÁlvaroA.GutiérrezVargas, спасибо за ваш ответ. Моя цель — работать с обоими, я предпочитаю использовать R, а мой коллега предпочитает Stata. И есть определенные вещи, которые мы предпочитаем делать с одним R, а другие со Stata. Суть в том, что я хотел бы иметь возможность легко переходить из одной программы в другую. но мы сталкиваемся с невозможностью плавного перехода от одной программы к другой.
Уважаемый @Alex, я вижу, что проблему решить сложнее, чем кажется, в частности, из-за расширения URL. Предполагая, что у вас есть доступ к Stata версии 15 или более поздней (из-за длины строк, которые можно сохранить), я бы обработал все, что вы хотите сделать, используя либо R, либо Stata, и сохранил вывод в CSV. Позже вы можете продолжить с сохраненного файла CSV и перейти к следующему анализу в любом программном обеспечении, которое вам нравится, не ограничиваясь файлами .dta
o .rds
.
Уважаемый @ÁlvaroA.GutiérrezVargas, большое спасибо за ваш ответ. На самом деле я боюсь, что проблема связана с тем, что две мои строки символов содержат до 4200 символов. Использование cvs, вероятно, является лучшим вариантом, если никто не может дать представление о том, как импортировать такие .dta
файлы с длинными строками в R.
В случае, если кому-то интересно, я смог преодолеть проблему в 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' }
@ Алекс, я завершил всю нашу дискуссию ответом на твой вопрос, главным образом потому, что мне было любопытно узнать всю эту проблему. Если у вас есть какие-либо вопросы или комментарии, я был бы более чем счастлив прочитать вас.
Я просто хочу подвести итог всему, что упоминалось в комментариях.
Из официальной документации Stata у нас есть следующее:
Переменные strL могут иметь длину от 0 до 2 миллиардов байт. Переменные strL не должны быть длиннее 2045 байт. Переменные str# могут хранить строки размером до 2045 байт, поэтому strL и str# перекрываются. Это перекрытие сравнимо с перекрытием числовых типов int и float. Любое число, которое может быть сохранено как целое, может быть сохранено как число с плавающей запятой. Точно так же любая строка, которая может быть сохранена как str#, может быть сохранена как strL. Обратное неверно. Кроме того, переменные strL могут содержать двоичные строки, тогда как переменные str# могут содержать только текстовые строки. Таким образом, аналогия между str#/strL и int/float является точной. Будут случаи, когда вы захотите использовать переменные strL вместо переменных str#, точно так же, как бывают случаи, когда вы захотите использовать переменные с плавающей запятой вместо переменных int.
Приведенная выше информация заставляет меня сделать два вывода, прежде чем я попытаюсь воспроизвести вашу проблему.
В вашем случае использование strL
не требовалось.
Использование 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 = "eSw0qZcVs5DHU2GxgRo1Seo9uTwJ0MvHXyYUQidJMRWw8KW1310Ec242O6D4xrLziO4c56WgluSddTy0Q64QapkwGgOMZdy8ru0fyss0nwJvF4M3kBjYGF00ZsvQGYt4DjF51R3vxTzUx4xlApKwaoRADIgFlXvBh2Bug0VVhmXR3uInHDfpmID57kVWiyxX1gELdyPMVzJWizEHVx2GpjBsm1UdRphDdukFtFrnkr1HFRXBekxHkW3uOCHz0wnyDBfwitDGHosctRrWPhIjujnoalOaHkI5jbnENSNJEsOdGohoe5QKZIxtXmVbD4l8m8wLCbuSjZLw8NzU5vjPX57T2yWWasdFMIHk3kFipT0CG3dNForECS8UiW6ZWSIEmO2V62uakfrxTsRb9fIFVBUIHpGizeR0b27OnfSVB2wE2Ix0ij7kR19jz0wIh35fbwkJWqLq93pfHEtGu0FTb8H5A4XNOcR8chEAQBI7zV3rosSGnSP2h9QZtuSAcz1TrRHNMpCguvNf1DD72TCfCaiBXyflOCre7f5zchLA7k2cQ5qi4fBMVc9GnAdGB2vnjFeFlwaUD0AEUhfSJJINRQ2CKfJegqUL0jBgHBVy5cYCNxsP8Gu8NXRUo6vvyiTJMDcBkL0JKNOT4usSDi4v86cJNzQQa3ArafRzOv1RFz8BfI7pP7rXDLD6d1Z1miCqTZ8UtJBVQ0Z0eCQmTrlAvlu5busOjcAl4ZV7THH6qCV8tI53zh1THBfjnEgoPxy8UIaIK6tXDUM4RFMMd1366324mJEVwyvc5CWgzPian39Q3GFLl6zXCfD4pw7rSUmH5CNOmKgPihxPbV9NSBxiwVK3M07KFS2hZbf3ZDB4CBSJV9geFWKZlR3XNrsPudQgkpsdywNNjZTDwD2RiHF7kQAgyEW7q1w42OC2IbreBBtiPekx6yzCEWBEokLwfhrhbOnDwcnFmfKjnrxCbqypXrSnyvrUP2nUQ9vBmdxCqiVLrBHuDi6Wv2U4vyZ7dTqk84WmnwACXo5PbYY2dmhtjscLMpRw4Q6xVUEWC3qPMnQkbI1UKEq1NfOrF0X8nC0rqrwHQuNuJqHuebJj5AMXVgyZWTaqYIb4gkbGaEze3wNmHbbj1q2bmumiwd6RZRSdx7U3ZwozO9kTkZ69NHFSa2QDi8GrhgvBDMshJVaOR9K8tWcpa2QrFD7cI0ZqzneLXHXm6LsOmtZPFmikKfyts1pASGwZ8DzuWfT3j0daNmyk6y0HwHwM98KOyeuSXnQJOJzunAXkidv90hrgviWUhP70Nrx527JI7vpRr2dClBBnzO2O7YwjTdKTrmfcPs9z4iLeroo20Jg9ODHjvUYWtLRTOKrgvYAgywkj2PoVdwmuYK32UKcqH5EdhPHxWarjsqUuBb40u6nUGIQ0YS7ZuzsnVDerB8hO3rCl0FlMMYgRh4vdPcEG23JQoIwTvdujULg6Lpplyt6yK16UhVSklj6aVNIoA4zr51dULyOzWF9ZqlZz7l90QpXvLuRD9Elr5gxWvNW4fvkCAU3kpEv0s7gHS7ytjNxm0WLk74bN1iP8ZjcxXXBqwtatCo9e1Ayc59VYR9RVxtfvilb038WpHglhWEZoK91rumPSFiCJWUmlkL6P4SAbz5b6LDdW9ybiN8zdZmNtQ2px556d7DF5RRcXgLocLH37Uh6uU9cz2wmWRrcJS4rO9MkUe6KSuVjVLXSsk6J1bnvvagWl4BkY8ZPm0iBg4XXTkRAjfVgnfex1hee47b6k9c5gdS6AJSVazCPpXQJlGJ7NpyAn3hXdHkhaGtokTmne6Zag8DterOyDldPXHXwrG7PgtsmREc0VugLVPrYEbdf9QMHBtGQLwQz04Gyg2lspZ5HbGnOkfI0MTanuMN7XnWdcGBko9gmQKbpONgPqg8POcpxG2aRefswG090hvYKj5gzp3r1nitZZhBm8KDUT8P2Wy06hPxrkZinMGmBv2SIDegXr5uzceHymEnyMQZINS96QCyTiV7z1X1NZ3IBDfVPZTZ9bRxpKyMbAnYzFhx9PYSkescyMMtsGOEli1gFp2PWcqO4bpj0EnKjgWf9ae2R5nDKIkVbsNRCik3JrCM7WjHPfwdZSiA335Eyl0yoHQWjp6YJrR8ykOtw3zL2XHa2ilKIRSypG5dtDwjuqLI1fb7fB5wiG3LuowKqam8HY86aDsuu0DkpED9mAxoSvE7V6WPs5ptg31yoUOgGK1rvGtdpY7CHkaBmmv0jKNYjcZiuET6Q0If2IO36HafXJN8onjMvYadAypEY4IAxkmU2yemCFQkdDBuhr8G4DWcGO46W24QOvMghH6k3HVHeDgj5dNXKIz3rqbCC6tSNMptuQhoM2eWnwBFw6PzNIqKwB6qxbJMs9wxqvDEJlQkKgMZN4HJu1hNFpXIePLN8dSsV8xhgb1pxwFaqhLQMoYXcgobOdcrb7DDpJFbWhUXKn3WHEjO8nk4EAuNmIUdyfWxwxPPmTLEyohT7QrcjvRph82n64aRJIcyDPCho8pqtCTve84PAp4jIeechI8sl92e94jsX7XTZu3LaqDGkEEtcmp69ZqPA5Ev9NZv5ovmWNiu39kKu7QW0YnXGCvorirdScdCow4NyLgnpoAEG0FPz52oN7xU5xyTgY0x5Hel5GDsA28Qoy463tyBNuT51gQROr9XqgiM9Voq0ax1vI8QKFMLXwaLtHwPC7TkFtJbXYNmPt2kXzQ1EjLq0DGiyKd0BFMww3zpEjeSUS7KhCrf5qU7aDjIkVniPs6TGkTBOwG9ItrUv50WJfqgOd6ngHfYWzJFIAgZnGjXhtkHartO3F19iPs5VHRhTEUw2HZbgnTjmf2NmJ1onUkMNSFUMPrNkrfxl78GHNjJrGAkRU0jlXqAuIK8v6uYh4oyqSrFtzPru8GNIWCbka6LKLrMcCysoDk7VQI12xzELxUebiUsnLYCrnvmJtD0T7yv9M8H8rI4YsdbzD3forc56uvwqS0h0Bl6Sw71n781EC0R0V6067RA2TRZ39fs7yXYZ4O5pQ1uHn0qV82aZI1kHxWVJ1omu81KqoFpTnB0QuNd62AeVKRiuMiAf2UFhy40vFgFElRZFipH1TrJAuFYcgwd38kJWTGTYyW51z1DQfVZnlIegEfZQPTjnhFroayXw55MKnJGiVPQ4R0A2nO5LCDmDFmC8SyLz62pn0aQb5tvlQs5Es7woSf3SbxcKh9JndW42V8hQn4uXxbEKhAX9f48VJg5xXYsMOaBz4h0UfsOrOucFH3YVA9c7TVszXbSq7kRQkpsy3xkunDaIfdiAx5wdLE7LbPhUwrC1FWnCa2qQQxNUimxrQ35Woar9tNQSwpVd8ybEaivgQ77HPSYjTdkKX2j2TBCzmGVBesOUnWI9r34kRO5xPsPPDoJvLQe6kns75Yjcuz82OEuUai1PLVRKmzkRjyLp3tt5YDkjzuYCOWNchY3Eup1IEDvGf64wu4S1qLvRrl6HI9jZj7Li2GZc9grCTxbqpUQgCbCxdgmS6a396AJNijmG8uNnchGPlnNVm6DskG7T2pWasVuuhYhkyFNoUWuY5mBXurDMEDyyZPxlY9nlQYKHBNgg6ZnNEYnwCqTLzudDBQ48YG9r3700uvz83jJAX18s2Kjm2LlmOuPJON6rzbPua8Ac2Y0HPuQZD9Ikcim2MOyR9mbvtRTPeLAX3issevCDYaBiG6BFMaN9rW7j1UnlKQZYgTCveE4oH8tT7QGwdWENAjW4kGjS93zCS6QYxyUjg03er43KivMQOVHaT3iznZnQD3Nk5c0T9IKqRpcytY7JaRV7kmayUmKc4d1ApFqY8imlu2iTMiVfY16qMqDeulTtcKjKUuyWBrJSENwv238nWXQudShLeCsiwUMUnJvXyHdSsmAaaoG5O3RA4GkiQVAiX63tWPl6GNfweFAcpxoD4x8hZpbQ1SaBo3pRNwwHuAvzOwm0jKWndfugKqlUmPoDZb9Bx6dzDolUJtHSNYVrOACFY26SyeyeiFHnnd6wZFypkDGL4LgeBbU8TqJTjO2lFXVmCQZjTnO75V43vJKoHUrRSUkZJYTyl3c8tqWJmrUZ7lJo4cUrGzoudgzDHH8N8H73TwXboF8rbQ8i4yb9w51L0EnCd3kdmSXI0PJxuQ9CQ8AD9WKTwvEaSWDTZ"
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")
Единственными отличиями здесь могут быть:
Наконец, я думаю, что источником проблемы был не strL
тип данных, а память, доступная на вашем компьютере, которая, вероятно, была решена вашим compress
шагом в цикле for, который вы описали.
PS: Все запускалось на Win10. R версия 4.0.3 (2020-10-10) и haven_2.3.1
Хорошая работа. Пожалуйста, убедитесь, что мои правки не изменили вашего предполагаемого значения.
Смысл остался прежним после издания. Спасибо за исправления @NickCox.
FWIW, у меня была эта проблема, и она была исправлена запуском compress
перед сохранением в stata. Кое-что о наличии данных strL. Это не проблема системной памяти.
Если какой-либо обходной путь не сработает, как насчет экспорта в файл другого типа, например csv, в Stata, а затем импорта в R с использованием файла csv?