2

我正在尝试处理一个名为.TextGrid(由 Praat 程序生成)的“分段文件”。)

原始格式如下所示:

File type = "ooTextFile"
Object class = "TextGrid"
xmin = 0 
xmax = 243.761375 
tiers? <exists> 
size = 17 
item []: 
    item [1]:
        class = "IntervalTier" 
        name = "phones" 
        xmin = 0 
        xmax = 243.761 
        intervals: size = 2505 
        intervals [1]:
            xmin = 0 
            xmax = 0.4274939687384032 
            text = "_" 
        intervals [2]:
            xmin = 0.4274939687384032 
            xmax = 0.472 
            text = "v" 
        intervals [3]:
[...]

(然后将其重复到 EOF,间隔 [3 到 n] 用于文件中的 n 项(注释层)。

有人提出了 使用rPython R 包的解决方案。

很遗憾 :

  • 我对 Python 没有很好的了解
  • rPython 的版本不适用于 R.3.0.2(我正在使用)。
  • 我的目标是专门在 R 环境下为我的分析开发这个解析器。

现在我的目标是将这个文件分割成多个数据框。每个数据框应包含一个项目(注释层)。

# Load the Data
txtgrid <- read.delim("./xxx_01_xx.textgrid", sep=c("=","\n"), dec=".", header=FALSE)
# Erase White spaces (use stringr package)
txtgrid[,1] <- str_trim(txtgrid[,1])
# Convert row.names to numeric 
num.row<- as.numeric(row.names(txtgrid))
# Redefine the original textgrid and add those rows (I want to "keep them in case for later process)
txtgrid <- data.frame(num.row,txtgrid)
colnames(txtgrid) <- c("num.row","object", "value")
head(txtgrid)

的输出head(txtgrid)非常原始,所以这里是 textgrid 的前 20 行txtgrid[1:20,]

   num.row          object                value
1        1       File type           ooTextFile
2        2    Object class             TextGrid
3        3            xmin                   0 
4        4            xmax          243.761375 
5        5 tiers? <exists>                     
6        6            size                  17 
7        7        item []:                     
8        8       item [1]:                     
9        9           class        IntervalTier 
10      10            name              phones 
11      11            xmin                   0 
12      12            xmax             243.761 
13      13 intervals: size                2505 
14      14  intervals [1]:                     
15      15            xmin                   0 
16      16            xmax  0.4274939687384032 
17      17            text                   _ 
18      18  intervals [2]:                     
19      19            xmin  0.4274939687384032 
20      20            xmax               0.472 

现在我对它进行了预处理,我可以:

# Find the number of the rows where I want to split (i.e. Item)
tier.begining <- txtgrid[grep("item", txtgrid$object, perl=TRUE), ]
# And save those numbers in a variable
x <- as.numeric(row.names(tier.begining))

这个变量x给了我数字1,我​​的数据应该被分成几个数据帧。

我有 18 个项目 -1 (第一项是 item[] 并包括所有其他项目。所以向量x是:

     x
    [1]     7     8 10034 14624 19214 22444 25674 28904 31910 35140 38146 38156 38566 39040 39778 40222 44800
[18] 45018

我如何告诉 R:以这样的方式在多个数据帧中分割这个数据帧textgrids$nameoftheItem,以便我获得与项目一样多的数据帧?,例如:

textgrid$phones
         item [1]:
            class = "IntervalTier" 
            name = "phones" 
            xmin = 0 
            xmax = 243.761 
            intervals: size = 2505 
            intervals [1]:
            xmin = 0 
            xmax = 0.4274939687384032 
            text = "_" 
            intervals [2]:
            xmin = 0.4274939687384032 
            xmax = 0.472 
            text = "v" 
            [...]
            intervals [n]:
textgrid$syllable
    item [2]:
            class = "IntervalTier" 
            name = "syllable" 
            xmin = 0 
            xmax = 243.761 
            intervals: size = 1200
            intervals [1]:
            xmin = 0 
            xmax = 0.500
            text = "ve" 
            intervals [2]:
            [...]
            intervals [n]:
    textgrid$item[n]

我想用

txtgrid.new <- split(txtgrid, f=x)

但这条信息是正确的:

Warning message: In split.default(x = seq_len(nrow(x)), f = f, drop = drop, ...) : data length is not a multiple of split variable

我没有得到想要的输出,似乎行号没有相互跟随,而且文件都混在一起了。

我也尝试了一些which, daply (from plyr) &subset功能,但从未让它们正常工作!

我欢迎任何想法来正确有效地构建这些数据。理想情况下,我应该能够在它们之间链接项目(注释层)(不同层的 xmin 和 xmax),以及多个 textgrid 文件,这只是开始。

4

2 回答 2

2

向量的长度split应该等于data.frame.

尝试以下操作:

txtgrid.sub <- txtgrid[-(1:grep("item", txtgrid$object)[1]), ]

grep("item", txtgrid.sub$object)[-1]

splits <- unlist(mapply(rep, seq_along(grep("item", txtgrid.sub$object)),
                        diff(c(grep("item", txtgrid.sub$object), 
                               nrow(txtgrid.sub) + 1))))

df.list <- split(txtgrid.sub, list(splits))

编辑:

然后,您可以通过执行以下操作来简化数据:

l <- lapply(df.list, function(x) {
  tmp <- as.data.frame(t(x[, 3, drop=FALSE]), stringsAsFactors=FALSE)
  names(tmp) <- make.unique(make.names(x[, 2]))
  tmp
})

library(plyr)
do.call(rbind.fill, l)


  item..1..        class     name xmin    xmax intervals..size
1      <NA> IntervalTier   phones    0 243.761            2505
2      <NA> IntervalTier syllable    0 243.761            2505
  intervals..1.. xmin.1             xmax.1 text intervals..2..
1           <NA>      0 0.4274939687384032    _           <NA>
2           <NA>      0 0.4274939687384032    _           <NA>
              xmin.2 xmax.2
1 0.4274939687384032  0.472
2               <NA>   <NA>

注意:我在上面使用了虚拟数据。

于 2014-02-20T23:22:41.167 回答
0

您似乎在其他地方找到了一个很好的解决方案,但我想我不妨把它放在这里以供参考:

我最近完成了用于 Praat 对象的 JSON 转换器的第一个工作版本,可以用于此目的。您可以使用此插件save_as_json.praat中包含的脚本将 TextGrid 保存为 JSON 文件(同样:我是该插件的作者)。

从this other answer to a similar question复制,一旦你安装了插件,你可以使用SavePraat菜单中的脚本或从另一个脚本中运行它:

runScript: preferencesDirectory$ + "/plugin_jjatools/save_as_json.praat",
  ..."/output/path", "Pretty printed" 

完成后,您可以像这样将其读入R使用rjson

> library(rjson)
> tg <- fromJSON(file='/path/to/your_textgrid.json')
> str(tg)
List of 5
$ File type   : chr "json"
$ Object class: chr "TextGrid"
$ start       : num 0
$ end         : num 1.82
$ tiers       :List of 2
    ..$ :List of 5
    .. ..$ class    : chr "IntervalTier"
    .. ..$ name     : chr "keyword"
    .. ..$ start    : num 0
    .. ..$ end      : num 1.82
    .. ..$ intervals:List of 3
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 0
    .. .. .. ..$ end  : num 0.995
    .. .. .. ..$ label: chr ""
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 0.995
    .. .. .. ..$ end  : num 1.5
    .. .. .. ..$ label: chr "limite"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.5
    .. .. .. ..$ end  : num 1.82
    .. .. .. ..$ label: chr ""
    ..$ :List of 5
    .. ..$ class    : chr "IntervalTier"
    .. ..$ name     : chr "segments"
    .. ..$ start    : num 0
    .. ..$ end      : num 1.82
    .. ..$ intervals:List of 8
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 0
    .. .. .. ..$ end  : num 0.995
    .. .. .. ..$ label: chr ""
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 0.995
    .. .. .. ..$ end  : num 1.07
    .. .. .. ..$ label: chr "l"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.07
    .. .. .. ..$ end  : num 1.15
    .. .. .. ..$ label: chr "i"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.15
    .. .. .. ..$ end  : num 1.23
    .. .. .. ..$ label: chr "m"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.23
    .. .. .. ..$ end  : num 1.28
    .. .. .. ..$ label: chr "i"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.28
    .. .. .. ..$ end  : num 1.37
    .. .. .. ..$ label: chr "t"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.37
    .. .. .. ..$ end  : num 1.5
    .. .. .. ..$ label: chr "e"
    .. .. ..$ :List of 3
    .. .. .. ..$ start: num 1.5
    .. .. .. ..$ end  : num 1.82
    .. .. .. ..$ label: chr ""

或使用,例如,tg$tiers[[tier_number]]$intervals[[interval_number]]

于 2014-04-05T03:33:22.393 回答