dplyr summarise_all:无法强制“list”对象输入“double”

问题描述 投票:0回答:2

我正在尝试创建一个描述性统计表,为数据帧的每一列获取以下统计数据:均值、标准差、第 10 个、第 50 个和第 90 个分位数。然后我想转置数据集,以便列是不同的统计数据,每行都是数据集中的一个变量。

这是一个示例数据集:

dt <- data.frame(id = 1:100,
                 Numeric_Column_1 = rnorm(100),
                 Numeric_Column_2 = rnorm(100),
                 Numeric_Column_3 = rnorm(100),
                 Numeric_Column_4 = rnorm(100),
                 Numeric_Column_5 = rnorm(100))

以及应生成表格的代码:


desc_table <- dt %>% select(-id)  %>%
  dplyr::summarise_all(.funs = list(mean=mean(.,na.rm=T), sd=sd(.,na.rm=T), P10=~quantile(., c(0.1), na.rm=T), P50=~quantile(., c(0.5), na.rm=T), P90=~quantile(., c(0.9), na.rm=T)), na.rm=TRUE) %>%
  pivot_longer(cols = everything()) %>%
  separate(name,c("Variable", "Stat"),sep = "_") %>%
  pivot_wider(names_from = "Stat", values_from = "value") %>%
  mutate(mean = round(mean, 2), sd= round(sd, 2))

但是我收到以下错误: is.data.frame(x) 中的错误: 无法强制“list”对象输入“double” 另外:警告消息: 在mean.default(., na.rm = T) 中: 参数不是数字或逻辑:返回 NA

我该如何解决这个问题?

r dplyr
2个回答
1
投票

尝试这样做,修改您的代码以适应现代习惯用法,并将

<colname><separator><statistic>
习惯用法中的分隔符从
"_"
更改为
"."
以避免与列名称冲突(这可能是错误的根源)。 ..

dt %>%
  dplyr::summarise(
    across(
      -id,
      list(
        mean = \(x) mean(x, na.rm = TRUE), 
        sd = \(x) sd(x, na.rm = TRUE), 
        P10 = \(x) quantile(x, 0.1, na.rm = TRUE), 
        P50 = \(x) quantile(x, 0.5, na.rm = TRUE), 
        P90 = \(x) quantile(x, 0.9, na.rm = TRUE)
      ),
      .names = "{.col}.{.fn}"
    ) 
  ) %>%
  pivot_longer(
    everything(), 
    names_sep = "\\.", 
    names_to = c("Variable", "Stat")
  ) %>%
  pivot_wider(names_from = "Stat", values_from = "value") %>%
  mutate(mean = round(mean, 2), sd= round(sd, 2))
# A tibble: 5 × 6
  Variable          mean    sd   P10     P50   P90
  <chr>            <dbl> <dbl> <dbl>   <dbl> <dbl>
1 Numeric_Column_1 -0.04  0.94 -1.20 -0.0872  1.11
2 Numeric_Column_2 -0.15  1.03 -1.46 -0.107   1.07
3 Numeric_Column_3  0.11  1.01 -1.53  0.229   1.14
4 Numeric_Column_4  0.09  1.05 -1.17  0.103   1.53
5 Numeric_Column_5 -0.02  1.02 -1.34 -0.0238  1.38

.names
调用中使用
across
就不再需要
separate
步骤。

从长远来看,最好删除管道的最后一个元件并用

knitr::kable(digits = 2)
替换它。这可以保持摘要的内部准确性,同时根据您的显示要求对其进行格式化。

此外,请参阅此页,了解为什么应使用

TRUE
FALSE
而不是
T
F


0
投票

您应该使用

extract
而不是
separate
并将
~
添加到
across
内的函数调用中:

dt %>% 
  select(-id)  %>%
  summarise(across(everything(), list(mean = ~mean(., na.rm = TRUE),
                                      sd = ~sd(.,na.rm=TRUE), 
                                      P10 = ~quantile(., c(0.1), na.rm=TRUE), 
                                      P50 = ~quantile(., c(0.5), na.rm=TRUE), 
                                      P90 = ~quantile(., c(0.9), na.rm=TRUE)))) %>% 
  pivot_longer(cols = everything()) %>% 
  extract(name, into = c("Variable", "Stat"), regex =  "^([A-Z].*_\\d+)_(.*)")  %>% 
  pivot_wider(names_from = "Stat", values_from = "value") %>%
  mutate(mean = round(mean, 2), sd= round(sd, 2))

# A tibble: 5 × 6
  Variable          mean    sd   P10     P50   P90
  <chr>            <dbl> <dbl> <dbl>   <dbl> <dbl>
1 Numeric_Column_1  0.09  0.96 -1.17  0.0428  1.42
2 Numeric_Column_2  0.04  1.05 -1.09 -0.0829  1.42
3 Numeric_Column_3  0.09  1.05 -1.33  0.168   1.42
4 Numeric_Column_4  0     1.04 -1.29 -0.118   1.48
5 Numeric_Column_5  0.09  1.02 -1.11  0.0578  1.19
© www.soinside.com 2019 - 2024. All rights reserved.