Нарисуйте те же случайные числа с Stata и R - PullRequest
1 голос
/ 05 октября 2019

Я могу нарисовать одинаковые случайные числа с Stata и R. По сути, я хочу получить ту же серию случайных чисел с sample в R и rdiscrete в Stata. Тем не менее, я попытался привести полный, но небольшой, воспроизводимый пример на каждом языке.

Я думаю, что функция sample делает то же самое, что и функция rdiscrete, но я не уверен. Предполагая, что эти функции выполняют одно и то же, мне просто нужно, чтобы они возвращали одинаковые случайные числа.

Я использую Stata 12.

Вот мой R код:

set.seed(1234)

wave_of_cy  = 2
wave_obs = 20

fake_dat <- read.table(text = '
     nobs  p1   p2
      0   .20  .10
      1   .10  .15
      2   .10  .15
      3   .05  .10
      4   .05  .10
      5   .20  .05
      6   .10  .05
      7   .05  .05
      8   .05  .05
      9   .10  .20
', header = TRUE, stringsAsFactors = FALSE)

p_hrand  = fake_dat[, (wave_of_cy+1)]
pp_hrand = p_hrand / sum(p_hrand)

my_rdata = sample(nrow(fake_dat), wave_obs, prob=pp_hrand, replace = TRUE)
my_rdata

hrand    = fake_dat[my_rdata, 1]
hrand

Вот мой Stata код:

clear
set seed 1234
global wave_of_cy  = 2
set obs 20
local wave_obs = _N

clear
input nobs p1 p2
0 .20 .10
1 .10 .15
2 .10 .15
3 .05 .10
4 .05 .10
5 .20 .05
6 .10 .05
7 .05 .05
8 .05 .05
9 .10 .20
end
list
save fake_dat

clear

use "fake_dat.dta", replace
putmata fake_data = (nobs p1 p2), replace

mata:
     p_hrand  = fake_data[., $wave_of_cy+1]
     pp_hrand = p_hrand :/ sum(p_hrand)
     my_rdata = rdiscrete(`wave_obs', 1, pp_hrand)
     my_rdata
     hrand    = fake_data[my_rdata, 1]
     hrand
end

1 Ответ

2 голосов
/ 05 октября 2019

Как уже упоминалось, случайная генерация в программном обеспечении / языках нелегко тиражируется, так как каждый запускает разные алгоритмы даже с одним и тем же номером начального числа. Для того чтобы воспроизвести одно и то же случайное поколение, вам необходимо либо связать две платформы:

  • с двухязыковыми API (например, rpy2 для запуска R внутри Python, reticulateдля запуска Python внутри R или twister для запуска Python's random.random() внутри Matlab)

  • Запуск языка более низкого уровня, такого как C / C ++, который вызывается вприкладной уровень между обоими программами, такими как SAS и Stata ;

    Этот подход возможен здесь, поскольку R написан на C, Fortran, а R и Stata (будучи программным обеспечением, а не языком)написано на C, поэтому оба могут вызывать один и тот же алгоритм случайных чисел;

  • Запустить командную строку на любой платформе и экспортировать / импортировать полученные данные с обработкой ввода / вывода текста.

Ниже показан последний вариант.


R (вызов Stata в пакетном режиме , не предполагает пустых строк после самого последнегоend строка)

setwd("C:\\Path\\To\\Working\\Directory")
# RUN DO SCRIPT WHICH OUTPUTS LOG OF SAME NAME
system("C:\\Path\\To\\StataMP-64.exe /e do myStataScript.do")

# READ IN LOG FILE TO CHARACTER VECTOR
stata_log <- readLines("myStataScript.log")

# EXTRACT NEEDED hrand OUTPUT LINES (N=20)
stata_data <- stata_log[(length(stata_log)-26):(length(stata_log)-7)]

# MATRIX BUILD OF EXTRACT AND RETURN SECOND ROW (TO MIRROR STATA'S RESULTS)
sapply(strsplit(stata_data, "\\|"), as.integer)[2,]
# [1] 9 9 1 9 0 9 4 1 0 2 2 2 0 6 2 7 1 5 3 1

Stata (calling Rscript автоматический исполняемый файл)

Сначала добавьте необходимые строки в примере сценария R:

setwd("C:\\Path\\To\\Working\\Directory")

... original code ...

# SAVE hrand DATA TO DISK
write.csv(data.frame(hrand), "RandomSeedDataSample.csv", row.names = FALSE)

Затем запустите сценарий Stata:

* RUN R SCRIPT
shell "C:\Path\To\R\bin\Rscript.exe" "C:\Path\myRScript.R"

* IMPORT CSV FILE
import delimited using "C:\Path\To\Working\Directory\RandomSeedDataSample.csv", clear

* MATRIX BUILD (TO MIRROR R'S RESULTS)
putmata hrand = (hrand), replace

mata
    hrand
end

:         hrand
        1
     +-----+
   1 |  9  |
   2 |  3  |
   3 |  3  |
   4 |  3  |
   5 |  5  |
   6 |  3  |
   7 |  9  |
   8 |  2  |
   9 |  3  |
  10 |  4  |
  11 |  3  |
  12 |  4  |
  13 |  2  |
  14 |  8  |
  15 |  2  |
  16 |  6  |
  17 |  2  |
  18 |  2  |
  19 |  9  |
  20 |  2  |
     +-----+
...