从数据帧列表中重复绘制的绘图

时间:2015-06-14 19:22:47

标签: r ggplot2 nested-lists

我正在尝试探索大数据集,包括数据框架和图表。我想通过不同的度量(例如,sum(x),sum(x * y))和不同的子群来分析每个变量的分布。我有4个子群体,2个指标和许多变量。

为了实现这一目标,我制作了一个列表结构:

$variable1
...$metric1     <--- that's a df.
...$metric2
$variable2
...$metric1
...$metric2

在其中一个data_frames(例如,list $ variable1 $ metric1)中,我计算了variable1和四个群体组中每一个(在列中表示)的唯一值的分布。它看起来像这样:

$variable1$metric1
unique_values med_all med_some_not_all med_at_least_some med_none
1 (1) 12-17 Years Old      NA               NA                NA       NA
2 (2) 18-25 Years Old   0.278            0.317             0.278    0.317
3 (3) 26-34 Years Old   0.225            0.228             0.225    0.228
4     (4) 35 or Older   0.497            0.456             0.497    0.456


$variable1$metric2
        unique_values med_all med_some_not_all med_at_least_some med_none
1 (1) 12-17 Years Old      NA               NA                NA       NA
2 (2) 18-25 Years Old   0.544            0.406             0.544    0.406
3 (3) 26-34 Years Old   0.197            0.310             0.197    0.310
4     (4) 35 or Older   0.259            0.284             0.259    0.284

我想弄清楚的是循环列表列表(可能在此过程中融化DF)然后输出大量条形图的好方法。在这种情况下,对于每个数据帧,自然绘图格式将是一个堆叠条形图,每个子群体具有一个堆叠条形图,按变量的唯一值进行分组。

但是我不熟悉迭代绘图,所以我已经走到了尽头。我如何从该列表结构中绘制?或者,是否有一个更好的结构,我应该存储这些信息?

3 个答案:

答案 0 :(得分:2)

我发现嵌套列表非常难以使用,因此我将它们全部合并到一个标记变量名称和度量标准名称的数据框中:

lst <- list(alpha= list(a= data.frame(matrix(1:4, 2)), b= data.frame(matrix(6:9, 2))), beta = list(c = data.frame(matrix(11:14, 2))))
level1 <- lapply(lst, function(x) do.call(rbind, lapply(names(x), function(y) {x[[y]]$metric=y ; x[[y]]})))
dat <- do.call(rbind, lapply(names(level1), function(x) {level1[[x]]$variable=x ; level1[[x]]}))
dat
#   X1 X2 metric variable
# 1  1  3      a    alpha
# 2  2  4      a    alpha
# 3  6  8      b    alpha
# 4  7  9      b    alpha
# 5 11 13      c     beta
# 6 12 14      c     beta

现在,您可以使用标准工具来操作单个数据框来执行数据分析。

答案 1 :(得分:1)

这是一个开始:

lst <- list(alpha= list(a= data.frame(matrix(1:4, 2)), b= data.frame(matrix(6:11, 2))), 
                          beta = list(c = data.frame(matrix(11:14, 2))))

lst
$alpha
$alpha$a
  X1 X2
1  1  3
2  2  4

$alpha$b
  X1 X2 X3
1  6  8 10
2  7  9 11


$beta
$beta$c
  X1 X2
1 11 13
2 12 14

#We can subset by number or by name
lst[['alpha']]
$a
  X1 X2
1  1  3
2  2  4

$b
  X1 X2 X3
1  6  8 10
2  7  9 11

lst[[1]]
$a
  X1 X2
1  1  3
2  2  4

$b
  X1 X2 X3
1  6  8 10
2  7  9 11

#The dollar sign naming convention reminds us that we are looking at a list.
#Let's sum the columns of both data frames in the alpha list
lapply(lst[['alpha']], colSums)
$a
X1 X2 
 3  7 

$b
X1 X2 X3 
13 17 21 

让我们尝试找到每个数据框的每列的总和:

lapply(lst, colSums)
Error in FUN(X[[i]], ...) : 
  'x' must be an array of at least two dimensions

发生什么事了? R正确拒绝在列表上运行数组函数。函数colSums需要在一维上方提供数据帧,矩阵和其他数组。我们必须在另一个函数中嵌套lapply函数。逻辑可能变得复杂:

lapply(lst, function(x) lapply(x, colSums))
$alpha
$alpha$a
X1 X2 
 3  7 

$alpha$b
X1 X2 X3 
13 17 21 


$beta
$beta$c
X1 X2 
23 27 

我们可以使用rbind将data.frames放在一起:

rbind(lst$alpha$a, lst$beta$c)
  X1 X2
1  1  3
2  2  4
3 11 13
4 12 14

一定不要按照你想的方式去做(我已多次这样做了):

do.call(rbind, lst)
      a      b     
alpha List,2 List,3
beta  List,2 List,2

这不是您正在寻找的结果。并确保尺寸和列名称相同:

do.call(rbind, lst[[1]])
Error in rbind(deparse.level, ...) : 
  numbers of columns of arguments do not match

R拒绝合并在一个(alpha $ a)中有2列的数据帧和在另一个(alpha $ b)中有3列的数据帧。

我更改了lst使alpha$b有两列像其他列一样并组合在一起:

bind1 <- lapply(lst2, function(x) do.call(rbind, x))
bind1
$alpha
    X1 X2
a.1  1  3
a.2  2  4
b.1  6  9
b.2  7 10
b.3  8 11

$beta
    X1 X2
c.1 11 13
c.2 12 14

它结合了每个列表的元素。现在我可以将外部列表组合成一个大数据框。

do.call(rbind, bind1)
          X1 X2
alpha.a.1  1  3
alpha.a.2  2  4
alpha.b.1  6  9
alpha.b.2  7 10
alpha.b.3  8 11
beta.c.1  11 13
beta.c.2  12 14

答案 2 :(得分:1)

这是一个基于熔化列表(递归)的策略,

lst = list(alpha= list(a= data.frame(matrix(1:4, 2)), 
                       b= data.frame(matrix(6:11, 2))), 
           beta = list(c = data.frame(matrix(11:14, 2))))

library(reshape2)
m = melt(lst, id=1:2)
library(ggplot2)
ggplot(m, aes(X1,X2)) + geom_bar(stat="identity") + facet_grid(L1~L2)