【问题标题】:Keep labels of merged variables only - Stata仅保留合并变量的标签 - Stata
【发布时间】:2018-07-26 08:55:11
【问题描述】:

我有一个数据库A。我想将它与数据库B 中的一些变量 (它有数百个变量)合并。 B 中的所有变量都有标签。所以,如果我这样做:

use A.dta
merge 1:1 id using B.dta, keepusing(var1 var2) 

我从B 得到所有值标签,复制到A。

如果我这样做:

merge 1:1 id using B.dta, keepusing(var1 var2) nolabel

var1 和 var2 在 A 中没有标签。

merge 中似乎没有允许在两者之间提供解决方案的选项(即仅复制合并的值标签)。

一种解决方法是运行:

labelbook, problems
label drop `r(notused)'

在第一种方法之后。然而,每次合并完成时都需要运行它(我合并了很多次)。它也可能很慢(数据集B 有很多变量)。

另一种选择是创建一个临时数据集“B-minus”,其中仅包含我想要的变量和值标签,并从中合并。但这也需要运行上面相同的耗时代码,所以没有什么不同。

有没有“更好”的方法来实现这一点?


MCVE:

webuse voter, clear
label list // shows two variables with value labels (candidat and inc)
drop candidat inc
label drop candidat inc2 // we drop all value labels
merge 1:1 pop frac using http://www.stata-press.com/data/r14/voter, nogen keepusing(candidat)
label list // instead of having only the candidat label, we also have inc

【问题讨论】:

    标签: label stata


    【解决方案1】:

    merge 中没有这样的选项,但您可以简单地使用macro list manipulation:

    webuse voter, clear
    
    label list // shows two variables with value labels (candidat and inc)
    drop candidat inc
    label drop candidat inc2 // we drop all value labels
    
    local labkeep candidat // define which labels you want to keep   
    
    merge 1:1 pop frac using http://www.stata-press.com/data/r14/voter, nogen keepusing(candidat)
    
    quietly label dir
    local secondary "`r(names)'"
    display "`secondary'"
    
    local newlabels :  list secondary - labkeep
    display "`newlabels'"
    label drop `newlabels'
    
    label list
    

    【讨论】:

    • 谢谢。这在一个合并两个标签的简单示例中很好(这就是 MCVE 在这里不是很有用的原因)。然而,就我而言,我合并了很多次(大约 120 次),添加了更多标签以保持每次迭代。为了自动化保留哪些标签,我仍然需要运行labelbook,因为标签的名称可能不直观。我只需要像merge ... , merge_lab_only 这样的东西,merge 只保留合并的标签!令人惊讶的是该命令不包含这样的选项。
    • 您可以为merge 创建一个包装程序。通过这种方式,您可以简单地在一行中运行所有内容。但不要指望速度会有所提高。这是一个方便的问题,即使 merge 有这样的选择,它在速度方面也不会产生太大的影响。
    • 因此,Stata 处理变量和标签的方式似乎使得它实际上不可能以快速的方式实现我想要的(这可能解释了在合并时复制所有标签的奇怪行为,以加快速度合并)。
    • 另一个选择是尝试merge 的nolabels 选项。然后你可以创建一个循环来在最终数据集中写入你想要的任何标签。
    • 我找到了另一种方法。看我的回答:)
    【解决方案2】:

    更新:不使用保留/恢复(感谢@Pearly Spencer 强调这一点)进一步提高了方法的速度。要查看保留/恢复的旧代码,请参阅the older versions of this answer。


    我想我找到了一种更快的方法来解决问题(至少从使用timer on、timer off 的结果来看)。

    因此,回顾一下,当前缓慢的方法是合并数据库,然后使用

    删除所有未使用的标签
    labelbook, problems
    label drop `r(notused)'
    

    另一种更快的方法是加载较小的数据集,仅使用所需的变量。这将仅包含所选变量的标签。然后,将这个较小的数据库与原始数据库合并。重要的是,合并方向是相反的!通过这种方式,我们消除了保留/恢复的需要,正如@Pearly Spencer 所建议的那样,这可能会减慢速度,尤其是在较大的数据集中。

    就我原来的例子而言,代码是:

    *** Open and work with dataset A ***
    
    use A.dta // load original dataset
    ... // do stuff with it (added just for generality)
    save A_final.dta // name of final dataset
    
    *** Load dataset B with subset of needed variables only ***
    
    use id var1 var2 using B.dta, clear // this loads id (needed for merging), var1 and var2 and their labels only!
    
    *** Merge modified A dataset into smaller B dataset ***
    
    merge 1:1 id using A_final.dta, keep(using match) // we do not specify any variables to load, as all those in A_final.dta needed) IMPORTANT: if we want to keep all observations of the original dataset (A, which is the one being merged into B), we need to use "using" rather than "master" in the "keep()" option.
    save A_final.dta, replace // Create final version of A. Done!
    

    就是这样!我不确定这是否是最佳解决方案,但在我的情况下,我正在合并具有数百个变量的许多数据集,它的速度要快得多。


    MCVE 方面的代码是:

    *** Open original dataset and work with it ***
    
    webuse voter, clear
    label list // shows two variables with value labels (candidat and inc)
    drop candidat inc
    label drop candidat inc2 // we drop all value labels
    save final.dta
    
    *** Create temporary dataset ***
    
    use pop frac candidat using http://www.stata-press.com/data/r14/voter, clear // this is key. Only load needed variables!
    
    *** Merge temporary dataset with original one ***
    
    merge 1:1 pop frac using final.dta, nogen
    label list // we only have the "candidat" label! Success!
    save final.dta, replace
    

    【讨论】:

    • 好吧,您已经在原始问题中提到了这一点。请注意,在使用“真实”数据集时,preserve 和 restore 可能会引入相当大的开销。
    • @PearlySpencer 我的意思是运行use B.dta,然后运行keep id var1 var,然后使用这两个命令删除标签。从这个意义上说,这与另一种方法一样。我不知道use <varlist> using B.dta 语法,它只加载标签的一个子集。开销是什么意思?
    • 速度征税。 preserve / `restore' 在处理大型数据集时速度非常慢。我猜速度将取决于您的用例。
    • @PearlySpencer mmm,如果不保存/恢复,它会更快,同时保存工作数据集,然后反转合并的方向!将更新答案。
    • @PearlySpencer 已更新。现在更简单的代码。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多