【问题标题】:Randomise blocks of values随机化值块
【发布时间】:2020-09-24 05:11:51
【问题描述】:

我有一个数据集,其中有几个变量 - 长度、宽度等的测量值 - 和一个分组变量 - 行。我想以这样一种方式随机化数据,即行间方差保持不变,但变量之间的行协方差被破坏了。

以鸢尾花为例,在这里我可以通过物种的分组变量获得每个物种的值块以保持在一起,并根据每个特征单独随机分配新物种 - 正是我想要的 - 但它也将数据中的 NA。我怎样才能让这个减少,以便形状与原始数据相同?

library(data.table)
set.seed(21)

dtIris <- data.table(id = rep(1:9, times = 1), iris[c(1:3, 51:53, 101:103), ])

dtIris 

dcast(
  melt(dtIris, id.vars = c('id', 'Species'))[
    melt(dtIris, id.vars = c('id', 'Species'))[, 
      .('Species' = unique(Species), 'new' = sample(unique(Species))), by = variable], 
    on = c('Species', 'variable')][, -c('Species')], 
  ... ~ variable, value.vars = 'value')

这是将数据放入长格式,为每个性状采样物种的唯一值,将其合并回长格式数据,然后将其传播回宽格式。它正在将 NAs 留在新的 != Species 处。

    id        new Sepal.Length Sepal.Width Petal.Length Petal.Width
 1:  1     setosa           NA         3.5          1.4          NA
 2:  1  virginica          5.1          NA           NA         0.2
 3:  2     setosa           NA         3.0          1.4          NA
...

【问题讨论】:

    标签: r data.table dcast


    【解决方案1】:

    评论太长,因此发布答案。你有NA 的原因是因为你已经对每个variable 的数据进行了采样,因此你的new 变量和id 之间的比例发生了变化。

    library(data.table)
    
    dt1 <- melt(dtIris, id.vars = c('id', 'Species'))
    
    dt2 <- dt1[dt1[,.('Species' = unique(Species), 'new' = sample(unique(Species))), 
                    by = variable], on = c('Species', 'variable')]
    

    以前你拥有的是

    table(dt2$Species, dt2$id)
    
    #             1 2 3 4 5 6 7 8 9
    #  setosa     4 4 4 0 0 0 0 0 0
    #  versicolor 0 0 0 4 4 4 0 0 0
    #  virginica  0 0 0 0 0 0 4 4 4
    

    现在你拥有的是:

    table(dt2$new, dt2$id)
    #             1 2 3 4 5 6 7 8 9
    #  setosa     1 1 1 0 0 0 3 3 3
    #  versicolor 3 3 3 0 0 0 1 1 1
    #  virginica  0 0 0 4 4 4 0 0 0
    

    正如您之前看到的,每个id 中只有一个Species,但采样后它不是真的(请参阅id = 1 同时具有"setosa""versicolor",而以前它只有"setosa") .当 id = 1 的值不同时,new 变量不可能在 1 行中。

    【讨论】:

    • 谢谢 - 我知道这是原因。应该说,id列可以去掉。
    • id 只是表示哪个值将在哪一行中。如果您删除此 id 列,您需要有另一个 id 列来阐明哪个值将在宽格式中的位置。在dt2 中,每个id 值都有相同的Species 列,因此当您使用Species 列将数据转换为宽时,您将以您想要的方式获取数据。 new 列的情况并非如此,其中每个 id 都有不同的 new 值。如果这个解释不清楚,您能否从我的回答中取 dt2 并使用它显示您的预期输出?
    猜你喜欢
    • 2021-06-19
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    相关资源
    最近更新 更多