【问题标题】:How do I group 90th percentiles by two columns如何将第 90 个百分位数按两列分组
【发布时间】:2021-08-06 20:09:09
【问题描述】:

我正在使用大型数据框 7191 obs。 19 个变量。这些列是月、日、年和 Site1 到 Site16。其中,月份是六月、七月、八月、九月或十月。

这是我的数据的开头,我相信在 site1-site16 列中只有数字。目前,我正在仔细检查以确保。

dput(head(No_PS_for_Calculations ))
structure(list(Month = c("June", "June", "June", "June", "June", 
"June"), Day = c(1, 2, 3, 4, 5, 6), Year = c(1970, 1970, 1970, 
1970, 1970, 1970), Site1 = c("11.531", "12.298", "12.732", "12.619", 
"12.5", "13.201"), Site2 = c("11.185", "11.439", "12.17", "12.432", 
"12.337", "12.492"), Site3 = c("11.147", "11.496", "11.645", 
"12.208", "12.644", "12.971"), Site4 = c("11.393", "11.707", 
"11.961", "12.135", "12.809", "13.041"), Site5 = c("11.797", 
"11.925", "12.34", "12.525", "13.01", "13.548"), Site6 = c("11.853", 
"11.974", "12.16", "12.481", "12.459", "12.838"), Site7 = c("12.319", 
"12.46", "12.476", "12.729", "13.026", "13.032"), Site8 = c("12.557", 
"12.643", "12.789", "12.975", "13.202", "13.339"), Site9 = c("12.774", 
"13.337", "13.896", "13.897", "13.819", "14.054"), Site10 = c("12.819", 
"13.202", "13.783", "14.298", "14.284", "14.309"), Site11 = c("13.151", 
"13.556", "13.833", "14.08", "14.244", "14.841"), Site12 = c("13.61", 
"13.57", "14.111", "14.073", "14.331", "14.849"), Site13 = c("13.802", 
"13.872", "14.244", "14.249", "14.255", "14.818"), Site14 = c("14.138", 
"14.275", "14.332", "14.522", "14.244", "14.927"), Site15 = c("14.138", 
"14.616", "14.766", "14.697", "14.61", "14.694"), Site16 = c("14.208", 
"14.627", "14.928", "14.829", "14.69", "14.762")), row.names = 151:156, class = "data.frame")

对于我的分析,我有兴趣找到每年每个月的第 90 个百分位数。例如对于 1970 年,我需要 6 月、7 月、8 月、9 月和 10 月的第 90 个百分位数。我尝试了几种不同的方法,但总是卡在同一个地方,所以我想寻求帮助。

result <- No_PS_for_Calculations %>% 
  group_by(Year, Month) %>%
  summarise(across(Site1:`Site16`, quantile, probs = .9, .names = 'percent90_{col}'))
data.frame(result)

这会导致以下错误:

Error: Problem with `summarise()` input `..1`.
i `..1 = across(Site1:Site16, quantile, probs = 0.9, .names = "percent90_{col}")`.
x non-numeric argument to binary operator
i The error occurred in group 1: Year = 1970, Month = "August".

我已经能够找到按月分组的百分位数,但现在需要包括年份以进行进一步分析。

按年和月显示第 90 个百分位数的最佳方法是什么?

感谢您的帮助!

【问题讨论】:

  • (在 Stack 站点中格式化代码使用您尝试使用的代码围栏,但是...代码围栏 ``` 必须单独在线,不能与任何代码共享。唯一的例外情况是第一个栅栏上有语言提示,例如```lang-r。有关详细信息,请参阅stackoverflow.com/editing-help。)
  • 您的某个专栏可能是character,请查看str(No_PS_for_Calculations) 看看哪些是您的罪魁祸首。请注意,此处的Site1:Site16 将选择两者之间的任何列,而不管命名约定如何,因此这不仅仅是选择Site* 列(以防万一)。您也许可以执行No_PS_for_Calculations %&gt;% select(Year, Month, starts_with("Site")) %&gt;% group_by(Year, Month) %&gt;% summarise(...),删除所有非预期的列。
  • 如果没有代表性数据,我不知道我们还能做些什么来提供帮助。你能把dput(head(No_PS_for_Calculations ))的输出粘贴到code block吗?
  • 我将 dput(head(No_PS_for_Calculations )) 的结果添加到问题中。据我所知,所有网站栏都应该是数字的,因为它们都是通过外部模型以相同的方式派生的。
  • 当您发布该内容时,您是否将Site 中的 none 列是数字的,而全是字符串?似乎完整数据中的某处可能存在非数字,而不是此处,因此您需要验证您的 dara 源以解决该问题。完成此操作后,重新加载数据并确保将其作为数字加载。您当然可以使用as.numeric 就地修复列,但我怀疑您可能会从一行或多行收到警告(这是解决症状,而不是问题)。

标签: r dplyr


【解决方案1】:

您似乎在Site1Site16 之间的列中有一些非数字的内容。一些虚假数据:

set.seed(42)
No_PS_for_Calculations <- data.frame(Year = rep(2020:2021, each = 3), Month = rep(c("Aug","Sep","Oct"), times = 2), Site1 = runif(6), Quux = sprintf("%0.03f", runif(6)), Site16 = runif(6))
No_PS_for_Calculations
#   Year Month     Site1  Quux    Site16
# 1 2020   Aug 0.9148060 0.737 0.9346722
# 2 2020   Sep 0.9370754 0.135 0.2554288
# 3 2020   Oct 0.2861395 0.657 0.4622928
# 4 2021   Aug 0.8304476 0.705 0.9400145
# 5 2021   Sep 0.6417455 0.458 0.9782264
# 6 2021   Oct 0.5190959 0.719 0.1174874

No_PS_for_Calculations %>% 
  group_by(Year, Month) %>%
  summarise(across(Site1:`Site16`, quantile, probs = .9, .names = 'percent90_{col}'))
+ > Error: Problem with `summarise()` input `..1`.
# x non-numeric argument to binary operator
# i Input `..1` is `(function (.cols = everything(), .fns = NULL, ..., .names = NULL) ...`.
# i The error occurred in group 1: Year = 2020, Month = "Aug".

如果非数字数据(此处为"Quux" 列)不打算汇总,那么您可以选择需要的列以避免任何混淆:

No_PS_for_Calculations %>% 
  select(Year, Month, starts_with("Site")) %>%
  group_by(Year, Month) %>%
  summarise(across(Site1:`Site16`, quantile, probs = .9, .names = 'percent90_{col}'))
# # A tibble: 6 x 4
# # Groups:   Year [2]
#    Year Month percent90_Site1 percent90_Site16
#   <int> <chr>           <dbl>            <dbl>
# 1  2020 Aug             0.915            0.737
# 2  2020 Oct             0.286            0.657
# 3  2020 Sep             0.937            0.135
# 4  2021 Aug             0.830            0.705
# 5  2021 Oct             0.519            0.719
# 6  2021 Sep             0.642            0.458

另一个原因可能是合法的Site 列不是数字的,在这种情况下,您需要确定是否可以轻松转换为数字。例如,如果这里的"Quux" 被命名为"Site2"

names(No_PS_for_Calculations)[4] <- "Site2"

然后我们可以尝试内联转换:

No_PS_for_Calculations %>%
  mutate(Site2 = as.numeric(Site2)) %>%
  group_by(Year, Month) %>%
  summarise(across(Site1:`Site16`, quantile, probs = .9, .names = 'percent90_{col}'))
# # A tibble: 6 x 5
# # Groups:   Year [2]
#    Year Month percent90_Site1 percent90_Site2 percent90_Site16
#   <int> <chr>           <dbl>           <dbl>            <dbl>
# 1  2020 Aug             0.915           0.737            0.935
# 2  2020 Oct             0.286           0.657            0.462
# 3  2020 Sep             0.937           0.135            0.255
# 4  2021 Aug             0.830           0.705            0.940
# 5  2021 Oct             0.519           0.719            0.117
# 6  2021 Sep             0.642           0.458            0.978

当然,如果里面有非数字字符,你会得到NAs,这很容易在给定过滤器、清理器或类似的情况下修复。

【讨论】:

  • 有没有办法判断数字的东西是否被读取为非数字?
猜你喜欢
  • 2018-06-11
  • 2015-08-01
  • 1970-01-01
  • 2018-11-25
  • 2015-07-05
  • 1970-01-01
  • 2012-11-01
  • 2019-04-06
  • 1970-01-01
相关资源
最近更新 更多