从Stata中的外部数据字典分配值标签

从Stata中的外部数据字典分配值标签,stata,Stata,我想使用一个已经构建好的数据字典来标记变量值。 最小数据集: clear input q1p0 q1p1 q2p0 q2p1 q2p2 q2p3 1 1 1 1 4 34 1 1 2 2 3 36 1 1 1 4 2 45 1 2 2 4 2 46 1 1 1 3 2 23 1 1 2 4 1 35 1 1 2 2 3 22 1

我想使用一个已经构建好的数据字典来标记变量值。 最小数据集:

clear
input q1p0  q1p1    q2p0    q2p1    q2p2    q2p3
1   1   1   1   4   34
1   1   2   2   3   36
1   1   1   4   2   45
1   2   2   4   2   46
1   1   1   3   2   23
1   1   2   4   1   35
1   1   2   2   3   22
1   1   1   2   1   17
1   1   1   4   1   40
1   1   2   3   2   18
1   2   2   2   1   40
end
当然,通过手动阅读字典,我可以做到:

label define yesno 1 "Yes" 2 "No"
label values q1p0 q1p1 q2p0 yesno

label define workload 0 "No change" 1 "Very low workload" 2 "Low workload" 3 "More workload" 4 "A lot more workload" 98 "Don’t know"    
label values q2p1 q2p2 workload

label define yesnodont 1 "Yes" 2 "No" 98 "Don’t Know"   
label values q2p3 yesnodont
然而,我有许多需要标记的变量,因此使用循环的自动化方法会很有帮助。 最小字典:

clear
input str4 variable  str20 valuelabel value
q1p0    "Yes"   1
q1p0    "No"    2
q1p1    "Yes"   1
q1p1    "No"    2
q2p0    "Yes"   1
q2p0    "No"    2
q2p1    "No change" 0
q2p1    "Very low workload" 1
q2p1    "Low workload"  2
q2p1    "More workload" 3
q2p1    "A lot more workload"   4
q2p1    "Don’t know"    98
q2p2    "No change" 0
q2p2    "Very low workload" 1
q2p2    "Low workload"  2
q2p2    "More workload" 3
q2p2    "A lot more workload"   4
q2p2    "Don’t know"    98
q2p3    "Yes"   1
q2p3    "No"    2
q2p3    "Don't know"    98
end
library(dplyr)

valuelabels <- read.table(text="variable valuelabel value
q1p0                 'Yes'     1
q1p0                  'No'     2
q1p1                 'Yes'     1
q1p1                  'No'     2
q2p0                 'Yes'     1
q2p0                  'No'     2
q2p1           'No change'     0
q2p1  'Very low workload'     1
q2p1        'Low workload'     2
q2p1       'More workload'     3
q2p1 'A lot more workload'     4
q2p1          'Don\\'t know'    98
q2p2           'No change'     0
q2p2   'Very low workload'     1
q2p2        'Low workload'     2
q2p2       'More workload'     3
q2p2 'A lot more workload'     4
q2p2          'Don\\'t know'    98
q2p3                ' Yes'     1
q2p3                  'No'     2
q2p3          'Don\\'t know'    98", 
                 header=T, stringsAsFactors=F)
上述数据集中的变量表示要命名的
变量
,分配给
变量
特定类别的
值标签
,以及
变量
类别的

如何实现流程的自动化

我需要生成:

clear
input str4 variable  strL labelstatement
q1p0    `"1 "Yes" 2 "No""'
q1p1    `"1 "Yes" 2 "No""'      
q2p0    `"1 "Increased" 2 "Decreased" 3 "No change" 98 "Don’t know""'   
q2p1    `"0 "No change" 1 "Very low workload" 2 "Low workload" 3 "More workload" 4 "A lot more workload" 98 "Don’t know""'  
q2p2    `"0 "No change" 1 "Very low workload" 2 "Low workload" 3 "More workload" 4 "A lot more workload" 98 "Don’t know""'  
q2p3    `"1 "Yes" 2 "No" 98 "Don’t Know""'      
end
一个相关的问题之前已经发布过,但其中涉及到标记变量,而不是值。

在R中,我可以这样做: 首先创建最小字典:

clear
input str4 variable  str20 valuelabel value
q1p0    "Yes"   1
q1p0    "No"    2
q1p1    "Yes"   1
q1p1    "No"    2
q2p0    "Yes"   1
q2p0    "No"    2
q2p1    "No change" 0
q2p1    "Very low workload" 1
q2p1    "Low workload"  2
q2p1    "More workload" 3
q2p1    "A lot more workload"   4
q2p1    "Don’t know"    98
q2p2    "No change" 0
q2p2    "Very low workload" 1
q2p2    "Low workload"  2
q2p2    "More workload" 3
q2p2    "A lot more workload"   4
q2p2    "Don’t know"    98
q2p3    "Yes"   1
q2p3    "No"    2
q2p3    "Don't know"    98
end
library(dplyr)

valuelabels <- read.table(text="variable valuelabel value
q1p0                 'Yes'     1
q1p0                  'No'     2
q1p1                 'Yes'     1
q1p1                  'No'     2
q2p0                 'Yes'     1
q2p0                  'No'     2
q2p1           'No change'     0
q2p1  'Very low workload'     1
q2p1        'Low workload'     2
q2p1       'More workload'     3
q2p1 'A lot more workload'     4
q2p1          'Don\\'t know'    98
q2p2           'No change'     0
q2p2   'Very low workload'     1
q2p2        'Low workload'     2
q2p2       'More workload'     3
q2p2 'A lot more workload'     4
q2p2          'Don\\'t know'    98
q2p3                ' Yes'     1
q2p3                  'No'     2
q2p3          'Don\\'t know'    98", 
                 header=T, stringsAsFactors=F)
这是一个“我不会从那里开始”的例子。但考虑到你有,假设你读这些细节作为数据。然后是单一命令

gen line = "label define " + variable + " " + string(value) + " " + char(34) + valuelabel + char(34) + ", modify" 
将创建一个变量
,其内容适合导出并作为do文件执行

这里的
char(34)
字符。有其他方法可以确保添加文字引号,但风险相当低

否则,你有一个do文件的成分。你只需要添加一些文本并重新排序


您可以将这样的指令与真实数据混合,只要任何文本都可以放入字符串变量中。但这取决于您是否这样做。(我通常会使用任何喜爱的文本编辑器。)

让我们以显示标签的方式创建一个带有标签的数据集。首先, 让我们假设,为了更容易理解,我们正在讨论 一个国家。假设这个国家有4个州,每个州有4个区,每个州有4个镇

这为我们提供了1+4+4^2+4^3=85个对象

clear
set more off
set obs 85

gen name=""
replace name = "country" in 1
replace name = "state" in 2/5
replace name = "district" in 6/21
replace name = "town" in 22/85

bysort name: gen value = _n
gen label = name + strofreal(value)
太好了!现在我们有了标签名称、值和标签本身。让我们继续并将其保存为.dta文件以供以后打开。您想引用一个.csv文件,但都是一样的。您只需要使用
导入分隔的
而不是
稍后使用

tempfile labels
save `labels'
请注意,由于我引用的是临时文件,所以您需要将这些都放在一个.do文件中。我建议将其复制/粘贴到一个.do文件中,而不是直接逐行输入

现在我们需要创建一个需要标签的样本数据集,其中包含变量country、state、district和town

clear
set more off
set obs 1

foreach x in country state district town {
    gen `x' = _n
    expand 4
    sort `x'
}
duplicates drop town, force
现在,有一个独特的国家、4个独特的州、16个独特的地区和64个独特的城镇。它们都是一个整数变量,没有当前标签

现在,我们将创建一个保存此数据的循环,然后使用每个变量值所需的标签引用临时文件

foreach x in country state district town {
    tempfile `x'do                              
    preserve                                        
        use `labels', clear                             // Reference the "labels" tempfile we made earlier
        keep if name == "`x'"                           // Keep only the rows where name is the name of the label we want to define
        qui sum value                                   // Allows me to reference r(N) later, the number of rows in the dataset
        forvalues i = 1/`r(N)' {                        // Inner loop generates value/label pair for each unique value of x
            local value = value[`i']                    // Pulls out the value for row 1, 2, 3,... etc.
            local label = label[`i']                    // Pulls out the label string for row 1, 2, 3,.. etc.
            label define `x' `value' "`label'", add     // Define and continuously add to label definition each time it loops
        }                                               // End inner loop
        label save `x' using ``x'do', replace           // Saves label instructions in temporary do file so we can access it after "restore"
    restore
    do ``x'do'                                          // Re-create the labels in our main dataset (they were lost after "restore")
    label values `x' "`x'"                              // Apply label to values                                
}                                                       // End outer loop

瞧!已经为每个变量生成并应用了标签。答案似乎很长,但请记住,我们必须先创建模拟数据。如果您定义了标签,使“名称“标签文件中的变量名与您要分配该值的变量名相同。

在我写答案时,问题发生了很大变化。我现在对这个问题更困惑了。从某种意义上说,编写Stata命令是必要的,直接执行似乎比间接执行要好。如果生成变量行所需的所有内容都位于数据集中的同一行,那么您上面建议的代码行就可以工作。但这里需要从一行中提取一些值,然后将它们“粘贴”到另一行中。这就是为什么我想到了
by
命令。但是,我不确定by和foreach是否一起工作。我可以在R中这样做,就像我在上面的编辑一样。我不明白你的区别。“我的代码”处理数据输入以创建do文件的内容。如果你喜欢在R里做,我没问题,但那不是你最初的问题。我对R没有偏见,但我的单行解决方案(除了导出到文件)似乎比您的R代码更简单。这并不意味着如果你在R方面更强大,写作就更容易了。我仍然对你在这里的目标感到困惑
by
似乎与您的问题无关,
foreach
似乎没有必要,因为
generate
语句提供了一个自动循环,将指令
输入
作为数据。您的代码可以工作,但不能提供所需的输出。例如,在变量行的第一行
label define Q1P01“Yes”
上给出,而所需的输出是
label define Q1P01“Yes”2“No”
。缺少的部分为
2“否”
,需要从第二行拉出并粘贴到第一行。实际上,这是过程中最棘手的部分。R代码能够做到这一点,但我认为在STATA中也有可能,您所需的输出根本不是必需的。我提请您注意原始答案中每个命令行末尾添加的
,modify
,它完全解决了您的问题。有关此语法和其他语法,请参见
help label
。问题是每次编辑都会变形。这是完全允许的,但这使它很难遵循。具体有两点意见:一,。输出的最后一块不是合法的Stata代码。我不知道这是不是有意的。2.关于
concat()
块的相同注释。
concat()
块现在已删除。解释另一种方法总是受欢迎的,但与我的答案中的简短解决方案相比,这似乎需要做很多工作,而且它对相关数据集非常具体。此外,您(似乎)声称没有人在Stata中使用逐行命令输入。这可能是夸大其词,但这是不正确的。一行一行地进行通常是最好的方式,至少最初是这样。当然,我也不反对编程Stata。绝对是一个exag