【问题标题】:R: Adding "NA" factors to the "levels" functionR:在“级别”函数中添加“NA”因子
【发布时间】:2021-11-19 04:24:33
【问题描述】:

我正在使用 R 编程语言。在这个例子中,我有以下数据:

library("dplyr")

df <- data.frame(b = rnorm(100,5,5), d = rnorm(100,2,2),
                 c = rnorm(100,10,10))

a <- c("a", "b", "c", "d", "e")
a <- sample(a, 100, replace=TRUE, prob=c(0.3, 0.2, 0.3, 0.1, 0.1))

a<- as.factor(a)
df$a = a


f <- c("a", "b", "c", "d", "e")
f <- sample(f, 100, replace=TRUE, prob=c(0.3, 0.2, 0.3, 0.1, 0.1))

f<- as.factor(f)
df$f = f

 head(df)
          b        d         c a f
1  6.896434 2.037835  2.867707 e a
2 -3.314758 2.681726 20.038918 d d
3  2.018130 2.229342 -8.341578 c a
4  9.738082 1.127069 18.337212 c c
5  2.442182 3.475735 27.875924 c c
6  5.061937 1.098709  6.166077 a e

然后我有以下函数(“my_subset_mean”),它为“a、b、d、f”的不同子集评估 df$c 的“平均”值:

my_subset_mean <- function(r1, r2, r3, r4){  
  subset <- df %>% filter(a %in% r1, f %in% r4, b > r2, d < r3 )
  return(mean(subset$c))
}

在上一个问题中,我学习了如何编写一个循环来评估函数“my_subset_mean”的随机子集“a,b,d,f”:

create_output <- function() {
  uv <- levels(df$a)
  r1 <- sample(uv, sample(length(uv)))
 uv1 <- levels(df$f)
  r4 <- sample(uv1, sample(length(uv1)))
  rgb <- range(df$b)
  rgd <- range(df$d)
  r2 <- runif(1, rgb[1], rgb[2])
  r3 <- runif(1, rgd[1], rgd[2])
  my_subset_mean <- my_subset_mean(r1, r2, r3, r4)
  data.frame(r1 = toString(r1), r4 = toString(r4), r2, r3, my_subset_mean)
}

out <- do.call(rbind, replicate(100, create_output(), simplify = FALSE))

head(out)

             r1         r4        r2         r3 my_subset_mean
1 a, c, b, e, d          d 14.560821  3.4251138            NaN
2          d, e e, d, b, c  9.027482 -1.7108754            NaN
3             d e, b, a, d  1.447395  0.4279652      18.019990
4 a, e, b, c, d          e -6.807861  2.6301878       7.424415
5          a, d          d  8.307980 -1.8923647            NaN
6             a    b, c, a  7.180056 -0.4022791            NaN

问题:是否可以编写这个循环(“create_output”),以便有时不考虑“r1, r2, r3, r4”的值?例如

             r1         r4        r2         r3     my_subset_mean
1            NA          d     14.56    3.4251138            5
2          d, e, d, b,   NA    NA        -1.7108754         3.1
3             e, b,  d         1.447         NA           18.019990

我在想也许这可以在“级别”语句中指定:

uv <- levels(df$a)
  r1 <- sample(uv, sample(length(uv)))

在这里,我们可以看到“uv”的值:

uv
[1] "a" "b" "c" "d" "e"

是否可以做一些事情,使函数“my_subset_mean”有时会忽略“a、b、d、f”的某些子集条件?例如。 “平均值”仅使用“a,d”上的子集条件计算?

谢谢

【问题讨论】:

    标签: r function loops dplyr data-manipulation


    【解决方案1】:

    您可以修改 previous question 中的 my_subset_mean 函数以包含 r4 值。

    library(dplyr)
    
    my_subset_mean <- function(r1=NA, r2=NA, r3=NA, r4 = NA) {  
      if (all(is.na(r1))) r1 <- unique(df$a)
      if (all(is.na(r4))) r4 <- unique(df$f)
      if (is.na(r2)) r2 <- -Inf
      if (is.na(r3)) r3 <- Inf
      s <- filter(df, a %in% r1 , f %in% r4, b > r2 , d < r3)
      return(mean(s$c))
    }
    
    

    然后将create_output函数改成-

    create_output <- function() {
      uv <- levels(df$a)
      r1 <- sample(list(sample(uv, sample(length(uv))), NA), 1)[[1]]
      uv1 <- levels(df$f)
      r4 <-  sample(list(sample(uv1, sample(length(uv1))), NA), 1)[[1]]
      rgb <- range(df$b)
      rgd <- range(df$d)
      r2 <- sample(c(runif(1, rgb[1], rgb[2]), NA), 1)
      r3 <- sample(c(runif(1, rgd[1], rgd[2]), NA), 1)
      my_subset_mean <- my_subset_mean(r1, r2, r3, r4)
      data.frame(r1 = toString(r1), r4 = toString(r4), r2, r3, my_subset_mean)
    }
    
    set.seed(123)
    out <- do.call(rbind, replicate(100, create_output(), simplify = FALSE))
    head(out)
    
    #            r1         r4        r2        r3 my_subset_mean
    #1            NA          c        NA 4.2164973      12.095431
    #2 a, b, c, d, e    b, a, c        NA 0.4394423       7.130999
    #3            NA a, c, e, b  9.285701        NA       8.236054
    #4            NA         NA 14.060829 3.8960888      10.562523
    #5    c, b, a, d         NA        NA        NA       9.015613
    #6            NA    a, c, d  2.251218        NA      10.070425
    

    请注意,目前我没有分配任何出现NA 值的概率,因此将NA 作为任何参数的输入的概率是50%。如果您想更改它,您可以根据您在sample 中的选择分配probs 值。

    【讨论】:

    • @Ronak Shah:非常感谢您的回答!这是编写“probs”参数的正确方法吗?例如:r4
    • 如果数值变量比较多,我想你能找到最小变量的最小值和最大变量的最大值的范围吗?而不是写 rgd
    • 实际上外部样本仅采样两个值。一个是所有非 NA 值作为一组,另一个是 NA。所以你可以试试r4 &lt;- sample(list(sample(uv1, sample(length(uv1))), NA), prob = c(0.8, 0.2), 1)[[1]]。 range 在向量中给出越来越小的数字。
    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 2013-06-11
    • 2019-11-19
    • 1970-01-01
    • 2018-02-17
    • 2017-06-15
    • 2013-11-26
    • 2013-05-25
    相关资源
    最近更新 更多