14

我想以以下形式创建数据结构

Start, End, Elements
  3  , 6  ,  {4,5}
  4 ,  10 ,  {7,8,9}
   ....

换句话说,我正在沿着一条线移动一个球。“开始”代表球的最左边位置,“结束”代表最右边。“元素”意味着我以某种方式发现这些职位很特别。当元素的数量可以变得非常大时,最好使用什么数据结构?我唯一能想到的是一个数据框,其中第三列是一个适当格式化的字符串。如果我想查看集合中的每个数字,我将不得不解析字符串。R 是否有更好的数据格式?

谢谢!

4

2 回答 2

16

我的评论中提到的选项,即简单地使用其中一列的列表:

dat <- data.frame(Start = 3:4, End = c(6,10))
> dat
  Start End
1     3   6
2     4  10
> dat$Elements <- list(4:5,7:9)
> dat
  Start End Elements
1     3   6     4, 5
2     4  10  7, 8, 9

当然,您也可以完全放弃数据帧,而只需使用一个普通的旧列表(无论如何,这在很多情况下可能更有意义):

list(list(Start = 3,End = 6, Elements = 4:5),list(Start = 4,End = 10,Elements = 7:9))
[[1]]
[[1]]$Start
[1] 3

[[1]]$End
[1] 6

[[1]]$Elements
[1] 4 5


[[2]]
[[2]]$Start
[1] 4

[[2]]$End
[1] 10

[[2]]$Elements
[1] 7 8 9
于 2013-04-12T21:27:04.727 回答
7

您可以将其存储为一个高数据框而不是一个宽数据框,并且可能使用data.table它来有效地处理它。也就是说,每个元素一行而不是每个起始对一行

library(data.table)
dt = data.table(Start=c(3, 3, 4, 4, 4), End=c(6, 6, 10, 10, 10), Elements=c(4, 5, 7, 8, 9))
#   Start End Elements
#1:     3   6        4
#2:     3   6        5
#3:     4  10        7
#4:     4  10        8
#5:     4  10        9

这将使您可以很容易地对数据进行多种处理,例如确定每个范围中有多少元素:

dt[, list(Num.Elements=length(Elements)), by=c("Start", "End")]

#    Start End Num.Elements
# 1:     3   6            2
# 2:     4  10            3

这也将使数据易于使用该ggplot包进行绘图,该包通常期望数据采用高格式。

您可能会注意到这种数据结构很浪费,因为它为每个元素重复了 Start 和 End。但是,数据表的存储效率非常高——即使您的元素列表实际上是数百万长,它也可以很容易地适应并以这种方式进行处理。试试这样的一行:

dt = data.table(Start=1:1e6, End=1:1e6, Elements=1:1e6)

进行演示。处理起来肯定比将每个元素列表保存为字符串并每次拆分它要快。

于 2013-04-12T20:36:36.390 回答