【问题标题】:random sample from 7 columns for 80 rows来自 7 列 80 行的随机样本
【发布时间】:2019-01-12 17:52:59
【问题描述】:

我有一个 7 列 80 行的表格,看起来像这样,

         **`1`   `3`   `5`   `7`   `9`  `11`
          <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>**
      1     6     7     7     8    NA    NA
      2     6     7    13    13    14    NA
      3     9    10    10     8    NA    NA
      4     4     3     5     3    NA    NA
      5     3     2     5     5     6    NA
      6     7     7     5     4     5     5
      7     9     5     8     8    NA    NA
      8     6     6     7    NA     7    NA
      9    NA     6     5     5    NA    NA
     10     6     7     6     4     7     6
      # ... with 70 more rows

我需要对每行的 7 列之一进行随机抽样。例如第 1 (8) 行、第 2 (6) 行、第 3 (10) 行等所有 80 行。我可以使用示例功能吗?如果可以,那么如何使用?我可以用 NA 做什么。我需要进行 1000 次采样并计算每个样本的平均值。

任何帮助将不胜感激! 谢谢, 阿尔丁

【问题讨论】:

  • 您是否还想对NAs 进行采样,或者您只想对NA 值进行采样?
  • NA 会影响平均值,所以我需要将它们排除在外。更准确地说,在具有 NA 的行中,应始终使用当前值进行采样。如果我从抽样中排除 NA,是否会删除整行?

标签: r


【解决方案1】:

我们可以使用apply遍历行,获取非NA元素并获取sample

n <- 1000
lst <- replicate(n, apply(df1, 1, function(x) sample(x[!is.na(x)], 1)),
               simplify = FALSE)
Reduce(`+`, lst)/n

或者pmaprowMeans

library(tidyverse)
rowMeans(replicate(n, pmap_int(df1, ~
                          c(...) %>% 
                          na.omit %>%
                          sample(., 1))))

数据

set.seed(24)
df1 <- as.data.frame(matrix(sample(c(1:9, NA), 80 * 7, replace = TRUE), 80, 7))

【讨论】:

  • 非常感谢!我已经尝试过 apply 功能,它给了我我需要的东西。下一个重要问题是如何从 1000 次重复中获得 80 次随机抽取的观察值的平均值。我需要获取这 1000 种方法来分析它们是否与实验室测量的样本平均值有显着差异。希望您理解我的问题,因为它很难描述。
  • @AldinSelimovic 这就是 replicate 步骤,它做了 1000 次相同的事情,得到 meanrowMeansReduce+ 并除以长度
  • 更新:我已使用此函数获取 1000 次复制的平均值:mean2
  • 小心 - sample 有一个“功能”,可能会给您不正确的结果(或没有结果)。它可以通过df1[80,] &lt;- c(1, NA, NA, NA, NA, NA, NA) 触发,然后运行rowMeans...
【解决方案2】:

使用sapply()

sapply(as.data.frame(t(df1)), function(x) sample(na.omit(x), 1))

数据

df1 <- structure(list(X.1. = c(6L, 6L, 9L, 4L, 3L, 7L, 9L, 6L, NA, 6L
), X.3. = c(7L, 7L, 10L, 3L, 2L, 7L, 5L, 6L, 6L, 7L), X.5. = c(7L, 
13L, 10L, 5L, 5L, 5L, 8L, 7L, 5L, 6L), X.7. = c(8L, 13L, 8L, 
3L, 5L, 4L, 8L, NA, 5L, 4L), X.9. = c(NA, 14L, NA, NA, 6L, 5L, 
NA, 7L, NA, 7L), X.11. = c(NA, NA, NA, NA, NA, 5L, NA, NA, NA, 
6L)), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5", "6", "7", "8", "9", "10"))

【讨论】:

    【解决方案3】:

    这是一个使用 plyr::adply 的解决方案。

    library(plyr)
    
    # original dataset
    df1 <- data.frame(
       c( 6,  6,  9,  4,  3,  7,  9,  6, NA, 6),
       c( 7,  7, 10,  3,  2,  7,  5,  6,  6, 7),
       c( 7, 13, 10,  5,  5,  5,  8,  7,  5, 6),
       c( 8, 13,  8,  3,  5,  4,  8, NA,  5, 4),
       c(NA, 14, NA, NA,  6,  5, NA,  7, NA, 7),
       c(NA, NA, NA, NA, NA,  5, NA, NA, NA, 6)
    )
    
    
    # returns a single column from a row with NA's removed
    samplerow <- function(r) {
      # r is a single row of df
      # eliminate NAs from the dataset.
      r <- r[!is.na(r)]
      # Return one sample from this row
      # Not sure what happens if the row is all NAs. Don't do that.
      r[sample.int(length(r),1)]
    }
    
    N <- 1000
    # for N times,
    # for each row select 1 non-NA valued column,
    # take the mean of all rows
    replicate(N, mean(adply(df1, 1, samplerow, .expand=F)$V1))
    #...redacted...
    N <- 5
    set.seed(1)
    replicate(N, mean(adply(df1, 1, samplerow, .expand=F)$V1))
    [1] 6.0 6.2 6.2 7.0 7.1
    

    【讨论】:

    • 谢谢!您的解决方案效果很好。感谢大家的帮助。这是一个非常棒的社区!!!
    • 您好,该功能效果很好,但如果我想绘制 2 列或更多列怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2015-10-19
    相关资源
    最近更新 更多