【问题标题】:R - sample and resample a person-period fileR - 对人员周期文件进行采样和重新采样
【发布时间】:2016-08-10 16:17:22
【问题描述】:

我正在处理一个巨大的人期文件,我认为 处理大型数据集的一个好方法是使用采样和重采样技术。

我的人期档案是这样的

   id code time
1   1    a    1
2   1    a    2
3   1    a    3
4   2    b    1
5   2    c    2
6   2    b    3
7   3    c    1
8   3    c    2
9   3    c    3
10  4    c    1
11  4    a    2
12  4    c    3
13  5    a    1
14  5    c    2
15  5    a    3

我实际上有两个截然不同的问题。

第一个问题是我在sampling 个人期间文件中遇到了麻烦。

例如,我想采样 2 个 id 序列,例如:

  id code time
   1    a    1
   1    a    2
   1    a    3
   2    b    1
   2    c    2
   2    b    3

以下代码行用于对人员周期文件进行采样

dt[which(dt$id %in% sample(dt$id, 2)), ] 

但是,我想使用dplyr 解决方案,因为我对重采样感兴趣,特别是我想使用replicate

我有兴趣做replicate(100, sample_n(dt, 2), simplify = FALSE)之类的事情

我正在为dplyr 解决方案苦苦挣扎,因为我不确定grouping 变量应该是什么。

library(dplyr)
dt %>% group_by(id) %>% sample_n(1)

给我一​​个不正确的结果,因为它没有保留每个 id 的完整序列。

任何线索我可以如何采样和重新采样个人周期文件?

数据

dt = structure(list(id = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
3L, 4L, 4L, 4L, 5L, 5L, 5L), .Label = c("1", "2", "3", "4", "5"
), class = "factor"), code = structure(c(1L, 1L, 1L, 2L, 3L, 
2L, 3L, 3L, 3L, 3L, 1L, 3L, 1L, 3L, 1L), .Label = c("a", "b", 
"c"), class = "factor"), time = structure(c(1L, 2L, 3L, 1L, 2L, 
3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("1", "2", 
"3"), class = "factor")), .Names = c("id", "code", "time"), row.names = c(NA, 
-15L), class = "data.frame")

【问题讨论】:

  • 我还在 dplyr 中更新了一个复制版本

标签: r dplyr sample


【解决方案1】:

我认为惯用的方式可能看起来像

set.seed(1)
samp = df %>% select(id) %>% distinct %>% sample_n(2)
left_join(samp, df)

  id code time
1  2    b    1
2  2    c    2
3  2    b    3
4  5    a    1
5  5    c    2
6  5    a    3

这直接扩展到更多的分组变量和更高级的抽样规则。


如果您需要多次执行此操作...

nrep = 100
ng   = 2
samps = df %>% select(id) %>% distinct %>% 
  slice(rep(1:n(), nrep)) %>% mutate(r = rep(1:nrep, each = n()/nrep)) %>%
  group_by(r) %>% sample_n(ng)
repdat = left_join(samps, df)

# then do stuff with it:
repdat %>% group_by(r) %>% do_stuff

【讨论】:

  • 谢谢好点。但是,我正在尝试 replicate 采样,它适用于 replicate(100, sample_n(dt, 2), simplify = FALSE) 之类的东西,但不适用于更长的点序列。
  • @giacomoV 好的,已更新。我认为您应该将其放入问题本身。
【解决方案2】:

我想您正在做一些模拟,并且可能想要多次进行子集化。您可能还想尝试这种data.table 方法并利用键列上的快速binary search feature

library(data.table)
setDT(dt)
setkey(dt, id)
replicate(2, dt[list(sample(unique(id), 2))], simplify = F)

#[[1]]
#   id code time
#1:  3    c    1
#2:  3    c    2
#3:  3    c    3
#4:  5    a    1
#5:  5    c    2
#6:  5    a    3

#[[2]]
#   id code time
#1:  3    c    1
#2:  3    c    2
#3:  3    c    3
#4:  4    c    1
#5:  4    a    2
#6:  4    c    3

【讨论】:

    【解决方案3】:

    我们可以使用filtersample

    dt %>%
        filter(id %in% sample(unique(id),2, replace = FALSE))
    

    注意:使用 dplyr 方法指定的 OP 和此解决方案确实使用 dplyr


    如果我们需要使用replicate,一种选择是使用map from purrr

    library(purrr)
    dt %>% 
        distinct(id) %>% 
        replicate(2, .) %>%
        map(~sample(., 2, replace=FALSE)) %>%
        map(~filter(dt, id %in% .))
    #$id
    #  id code time
    #1  1    a    1
    #2  1    a    2
    #3  1    a    3
    #4  4    c    1
    #5  4    a    2
    #6  4    c    3
    
    #$id
    #  id code time
    #1  4    c    1
    #2  4    a    2
    #3  4    c    3
    #4  5    a    1
    #5  5    c    2
    #6  5    a    3
    

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 2014-05-04
      相关资源
      最近更新 更多