【问题标题】:Calling summary function inside lapply returning NaN values在 lapply 中调用汇总函数返回 NaN 值
【发布时间】:2021-07-29 13:13:13
【问题描述】:

假设我有这个数据框:

df <- structure(list(q1 = structure(c(2L, 2L, 4L, 
3L, 1L, 4L), .Label = c("I dont like\na thing", 
"I really dont like\nthat thing", "I like a\nthing", 
"Ambivalent\nabout the thing"), class = "factor"), q2 = structure(c(3L, 
2L, 1L, 1L, 4L, 1L), .Label = c("Neither like\nnor dislike", 
"Somewhat\ndislike", "Somewhat\nlike", "Strongly\ndislike", "Strongly\nlike"
), class = "factor")), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

我可以毫无问题地运行下面的 dplyr 块:

df %>%
    summarise(question = 'q1',
              n = sum(!is.na(q1)), 
              mean = mean(as.numeric(q1), na.rm = T), 
              sd = sd(as.numeric(q1), na.rm = T), 
              se = sd/sqrt(n), 
              ci_lo = mean - qnorm(1 - (.05/2))*se,  # qnorm() provides the specified Z-score
              ci_hi = mean + qnorm(1 - (.05/2))*se,
              min = min(as.integer(q1)),
              max = max(as.integer(q1)))


# A tibble: 1 x 9
  question     n  mean    sd    se ci_lo ci_hi   min   max
  <chr>    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int>
1 q1           6  2.67  1.21 0.494  1.70  3.64     1     4

但是,如果我尝试将它放在 lapply() 函数中并在列表中的所有列名上调用它,它会返回一堆 NaNNA 值。

summary_stats <- function(question){
  df %>%
    summarise(question = question,
              n = sum(!is.na(question)), 
              mean = mean(as.numeric(question), na.rm = T), 
              sd = sd(as.numeric(question), na.rm = T), 
              se = sd/sqrt(n), 
              ci_lo = mean - qnorm(1 - (.05 / 2)) * se,  # qnorm() provides the specified Z-score
              ci_hi = mean + qnorm(1 - (.05 / 2)) * se,
              min = min(as.numeric(question)),
              max = max(as.numeric(question))) 
}

colnames <- 
  df %>% 
  select(starts_with("q")) %>% 
  colnames

lapply(colnames, summary_stats)


[[1]]
# A tibble: 1 x 9
  question     n  mean    sd    se ci_lo ci_hi   min   max
  <chr>    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 q1           1   NaN    NA    NA   NaN   NaN    NA    NA

[[2]]
# A tibble: 1 x 9
  question     n  mean    sd    se ci_lo ci_hi   min   max
  <chr>    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 q2           1   NaN    NA    NA   NaN   NaN    NA    NA

Warning messages:
1: In mean(as.integer(question), na.rm = T) : NAs introduced by coercion
2: In is.data.frame(x) : NAs introduced by coercion
3: In mask$eval_all_summarise(quo) : NAs introduced by coercion
4: In mask$eval_all_summarise(quo) : NAs introduced by coercion
5: In mean(as.integer(question), na.rm = T) : NAs introduced by coercion
6: In is.data.frame(x) : NAs introduced by coercion
7: In mask$eval_all_summarise(quo) : NAs introduced by coercion
8: In mask$eval_all_summarise(quo) : NAs introduced by coercion

有谁知道我哪里出错了?我还想返回一个 tibble,每列有一行馈送到lapply 函数,而不是每列一个 tbl_df。这可能吗?

【问题讨论】:

    标签: r dplyr lapply


    【解决方案1】:

    您将列名传递给函数,而函数需要列数据。

    这是另一种方式-

    library(dplyr)
    library(purrr)
    
    summary_stats <- function(data){
           tibble(n = sum(!is.na(data)), 
                  mean = mean(as.numeric(data), na.rm = T), 
                  sd = sd(as.numeric(data), na.rm = T), 
                  se = sd/sqrt(n), 
                  ci_lo = mean - qnorm(1 - (.05 / 2)) * se,
                  ci_hi = mean + qnorm(1 - (.05 / 2)) * se,
                  min = min(as.numeric(data)),
                  max = max(as.numeric(data))) 
    }
    
    map_df(df %>% select(starts_with('q')), summary_stats, .id = 'question')
    
    #  question     n  mean    sd    se ci_lo ci_hi   min   max
    #  <chr>    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #1 q1           6  2.67  1.21 0.494 1.70   3.64     1     4
    #2 q2           6  2     1.26 0.516 0.988  3.01     1     4
    

    【讨论】:

    • 这很好用。谢谢罗纳克!我已将平均值线更改为mean = round(mean(as.numeric(data), na.rm = T), digits = 2),以尝试修复我看到的小数点数(在我的实际中,不是玩具,df)。但是现在的输出是2.360000e+00, 1.219097e+00, 2.770619e-03,分别表示均值、标准差和标准差。你知道我怎样才能打印出句号后的前两位数字吗?
    • 在控制台中运行options(scipen = 99)
    • 很好~这很有效,虽然最小值和最大值现在是 NA
    • 如果数据中有NA 值,请在maxmin 函数中添加na.rm = TRUE
    • 成功了。一如既往的感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    相关资源
    最近更新 更多