Разрушающие переменные с дробями - PullRequest
0 голосов
/ 22 ноября 2018

В моих данных есть строковые переменные, которые содержат дробные и нецелые числа.

Например:

3 2/3 
8 1/2
 1.65
6 1/4
0.235

Stata не может удалить эти переменные с помощью команды destring.

Что я могу сделать, чтобы преобразовать строковые переменные в числовые, чтобы я мог использовать их для анализа?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Код ниже, распространяющийся на регистры типа «3 2/3» или «- 6 1/4» (обратите внимание на пробелы), также может быть полезен для сохранения некоторых типов.

replace var1 = subinstr(var1, "- ", "-",.)
split var1, generate(x) destring force

egen y = ends(var1) if strmatch(var1,"*/*"), last
split y, destring force p("/")

replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
keep var1 x1 
0 голосов
/ 22 ноября 2018

Если все значения в ваших строковых переменных выглядят так же, как в вашем примере, вы можете сделать следующее:

clear

input str6 var1
"3 2/3"
"8 1/2"
"6/8" 
"-2/3"
"1.65"
"-6 1/4"
"-0.235"
end

replace var1 = subinstr(var1," ",":", .)
replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*") 
replace var1 = subinstr(var1,":"," ", .)

generate double var2 = real(var1) if !strmatch(var1, "*/*")

replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
               ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
               real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
               if strmatch(var1, "*/*") & !strmatch(var1, "-*")

replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
               ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
               real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
               if strmatch(var1, "*/*") & strmatch(var1, "-*")

Для получения дополнительной информации об использовании каждой функции введите help, а затем ееимя: real(), strmatch(), substr(), subinstr(), strpos(), abs().


РЕДАКТИРОВАТЬ:

вышеупомянутый подход основан на манипулировании строками с использованием строковых функций Stata и, следовательно, длиннее решения, предоставленного в другом ответе.

Тем не менее, вы можете немного сократить код и улучшить читаемость следующим образом:

local m1 !strmatch(var1, "* *")
local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
               cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" )  )

local e1  real(substr(var1, 1, strpos(var1, " ") - 1))
local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
          real(substr(var1, strpos(var1, "/") + 1, .)) )

generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
                cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )

В обоих случаях вы получите:

list, separator(0)

     +---------------------+
     |   var1         var2 |
     |---------------------|
  1. |  3 2/3    3.6666667 |
  2. |  8 1/2          8.5 |
  3. |  0 6/8          .75 |
  4. | -0 2/3   -.66666667 |
  5. |   1.65         1.65 |
  6. | -6 1/4        -6.25 |
  7. | -0.235        -.235 |
     +---------------------+
...