如何导入一些观察结果位于两行的 csv 数据

How to import csv data where some observations are on two rows

我有一个包含几百万行的数据集。它是 csv 格式。我想将它导入 Stata。我可以这样做,但有一个问题 - 一小部分(但仍然很多)的观察结果出现在 CSV 文件的两行中。大多数条目只出现在一行中。就用逗号分隔而言,占用 2 行的麻烦观察结果仍然遵循相同的模式。但在 Stata 数据集中,观察结果显示在两行中,两行仅包含总数据的一部分。

我用import delimited导入了数据。在 Stata 流程的数据导入阶段有什么可以做的吗?如果可能的话,我宁愿不必在原始 CSV 文件中处理这个问题。

***更新

以下是 csv 文件的示例:

var1,var2,var3,var4,var5 
text 1,    text 2,text 3   ,text 4,text 5
text 6,text 7,text 8,text9,text10
text 11,text 1     
         2,text 13,text14,text15
text16,text17,text18,text19,text20 

注意行尾没有逗号。另请注意,问题在于以 text 11.

开头的观察结果

这基本上就是它在 Stata 中的显示方式:

    var1     var2     var3     var4     var5 
1   text 1   text 2   text 3   text 4   text 5
2   text 6   text 7   text 8   text9    text10
3   text 11  text 1
4   2        text 13  text14  text15
5   text16   text17   text18   text19   text20

有时数字紧挨着 text 并不是错误 - 这只是为了说明数据比此处显示的更复杂。

当然,这就是我需要数据的方式:

    var1     var2     var3     var4     var5 
1   text 1   text 2   text 3   text 4   text 5
2   text 6   text 7   text 8   text9    text10
3   text 11  text 12  text 13  text14   text15
4   text16   text17   text18   text19   text20

如果 CSV 文件中引用了相关观察结果,那么您可以使用 bindquote(strict) 选项。

一些没有看到确切数据的推测:根据 Roberto Ferrer 的评论,您可能会发现 Stata 命令 filefilter 在导入前清理 csv 文件很有用。您可以使用基本字符以及更复杂的 \n\r 术语替换新旧字符串模式。

目前我无法提供任何代码,但我建议你好好看看help importinfileinfix 命令状态:

An observation can be on more than one line.

(我不知道这是否意味着 all 观察应该在几行上,或者它是否可以处理只有 some 观察不止一行。)

如果 help 文件中的示例和注释不够充分,还要检查手册。

我会尝试以下策略。

  1. 作为单个字符串变量导入。
  2. 计算每行中的逗号数,如果行不完整,则合并后续行。
  3. 删除多余的material。

逗号数将为

length(variable) - length(subinstr(variable, ",", "", .)) 

一个复杂的方法是(内联评论):

clear
set more off

*----- example data -----

// change delimiter, if necessary
insheet using "~/Desktop/stata_tests/test.csv", names delim(;)

list

*----- what you want -----

// compute number of commas
gen numcom = length(var1var2var3var4var5) ///
    - length(subinstr(var1var2var3var4var5, ",", "", .))

// save all data
tempfile orig
save "`orig'"

// keep observations that are fine
drop if numcom != 4

// save fine data
tempfile origfine
save "`origfine'"

*-----

// load all data
use "`orig'", clear

// keep offending observations
drop if numcom == 4

// for the -reshape-
gen i = int((_n-1)/2) +1
bysort i : gen j = _n

// check that pairs add up to 4 commas
by i : egen check = total(numcom)
assert check == 4

// no longer necessary
drop numcom check

// reshape wide
reshape wide var1var2var3var4var5, i(i) j(j)

// gen definitive variable
gen var1var2var3var4var5 = var1var2var3var4var51 + var1var2var3var4var52
keep var1var2var3var4var5

// append new observations with original good ones
append using "`origfine'"

// split
split var1var2var3var4var5, parse(,) gen(var)

// we're "done"
drop var1var2var3var4var5 numcom
list

但我们实际上并没有您数据的详细信息,因此这可能有效也可能无效。这只是一个粗略的草稿。根据数据占用的内存 space 和其他细节,您可能需要改进部分代码以提高效率。

注:文件test.csv看起来像

var1,var2,var3,var4,var5 
text 1,    text 2,text 3   ,text 4,text 5
text 6,text 7,text 8,text9,text10
text 11,text 1     
         2,text 13,text14,text15
text16,text17,text18,text19,text20

注2:我正在使用insheet因为我目前没有Stata 13。 import delimited 是可行的方法。

注 3: 有关如何计算逗号的详细信息,请参阅 Nick Cox Stata tip 98: Counting substrings within strings