如何在 R 中以 50/50 的昼夜时间比例为每个人提取每天一个随机的白天时间?

How to extract one random daytime per day for every individual with a 50/50 ratio of night and day times in R?

我对 R 的经验不多,我遇到了以下问题:我有 csv 格式的数据,这些数据来自带有日期时间戳和 GPS 位置的无线电项圈野猫(以及一些附加信息,如性别、年龄等。 ).我必须平衡每个人的数据集,因为修复(位置)的频率是不相等的。我想每天为每只猫的数据提取一个随机位置。此外,每个人选择的随机点应该有 50/50 的昼夜点比例。为此,我创建了一个列来定义该位置是在夜间还是白天记录的,但我不知道如何将比率规则添加到我的代码中。我也想知道是否可以在代码中保存随机选择的点,所以如果其他人再次运行它,他们会得到与我第一次提取的相同的随机点(我认为可以用 set.seed 来完成? ).我经常不知道如何组合我想使用的所有功能。

我想我成功地使用以下代码每天为每个人提取了一个随机点:

data %>% group_by(animals_id,utc) %>%
  sample_n(1) -> result 

但是我怎样才能包括每个人的 50/50 昼夜点数比例以及我怎样才能添加一个 set.seed 函数?

这是我的数据集的结构:

  X animals_id    acquisition_time longitude latitude
1 1          1 2010-05-01 02:59:00  7.604915 47.94362
2 2          1 2010-05-01 10:00:00  7.604967 47.94373
3 3          1 2010-05-01 16:59:00  7.605800 47.94379
4 4          1 2010-05-02 06:59:00  7.604969 47.94358
5 5          1 2010-05-02 13:59:00  7.604921 47.94008
6 6          1 2010-05-03 03:59:00  7.605051 47.94356
       projection collar_type study_area_id animals_age_class
1 EPSG:4326-WGS48         gps            13                 a
2 EPSG:4326-WGS48         gps            13                 a
3 EPSG:4326-WGS48         gps            13                 a
4 EPSG:4326-WGS48         gps            13                 a
5 EPSG:4326-WGS48         gps            13                 a
6 EPSG:4326-WGS48         gps            13                 a
  animals_sex        utc day_night
1           f 2010-05-01     night
2           f 2010-05-01       day
3           f 2010-05-01       day
4           f 2010-05-02       day
5           f 2010-05-02       day
6           f 2010-05-03     night
> 

我非常感谢每一个提示。

我试图定义一个函数,该函数根据可以对元素进行分组的列对数据框中的行进行随机抽样。此函数根据列的组拆分数据框,然后在每个组中随机 select 相等数量的行,然后将样本绑定回数据框。 n.each参数指定每组采样行数。如果未指定,则使用 n.each = 1。 通过指定 seed 参数可以再现随机采样的行集。如果未指定,则使用 seed = 1colname 是列名(应加引号)。 请注意,行名已从结果样本中删除。

这是函数和例子

library(data.table)
library(magrittr)

sample_equal <- function(df, colname, n.each = 1, seed = 1) {

  eqsamp <- function(df) {
    set.seed(seed)
    df %>%
      transpose %>%
      sample(n.each) %>%
      transpose
  }

  sampled <- df %>%
    split(df[colname]) %>%
    lapply(eqsamp) %>%
    do.call(rbind, .) 
  
  rownames(sampled) <- NULL
  colnames(sampled) <- colnames(df)
  return(sampled)
}

# Example1 : Applied to `iris`

iris %>% sample_equal('Species', 2, seed = 3)

#  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#1            5         3.6          1.4         0.2     setosa
#2          4.8         3.4          1.6         0.2     setosa
#3          6.5         2.8          4.6         1.5 versicolor
#4          5.9           3          4.2         1.5 versicolor
#5          6.5           3          5.8         2.2  virginica
#6          6.4         2.7          5.3         1.9  virginica

# Example2 : Multistage sampling to `mtcars` 

sample_equal(mtcars, 'cyl', 3, seed = 5) %>% 
sample_equal('gear', 2, seed = 3)

#   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#2 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#3 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#4 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#5 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#6 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2

要将其应用于您的数据,如果您想 select 一天一夜,这应该可行:

result <- data %>% group_by(animals_id,utc) %>% 
equal_sample('day_night', seed = 3) 

结果会有一晚和一天,但样本中的纬度和经度可能完全相同。

如果需要独特的位置,可以按纬度或经度分组,然后采样day/night。您还需要指定在每个纬度或经度中采样的 day/night 的数量。例如:

result2 <- data %>% group_by(animals_id,utc, latitude) %>% 
equal_sample('day_night', seed = 3)