由于列名不同导致生成输出表格出现问题

4
我希望解决一些关于列名的问题,这些问题在执行代码时会导致错误。下面我将展示一个简单的例子。请注意,我有一个名为 TimeofCalculate 的列,而下面的代码是 Timeofcalculate,因为代码中的 calculate 是小写的,所以会出现错误。然而,我希望任何一种写法都可以在代码中运行。此外,我有一个名为 Timeofcalculâte 的数据库列,其中包含了一个 â 字符,这是我所在地区常见的字符。因此,我希望解决上述问题。
library(dplyr)


Test <- structure(list(date1 = as.Date(c("2021-11-01","2021-11-01","2021-11-01","2021-11-01")),
                       date2 = as.Date(c("2021-10-22","2021-10-22","2021-10-28","2021-10-30")),
                       Week = c("Friday", "Friday", "Thursday", "thursday"),
                       Category = c("FDE", "FDE", "FDE", "FDE"),
                       TimeofCalculate = c(4, 6, 6, 3)), class = "data.frame",row.names = c(NA, -4L))


Test %>%
  group_by(Week = tools::toTitleCase(Week)) %>% 
  summarise(Time=mean(Timeofcalculate), .groups = 'drop')
2个回答

2

我认为在数据中,不同拼写的工作日是不可接受的,首先要解决这个问题。我们可以使用内置的tools::toTitleCase函数将首字母大写。

Test <- transform(Test, Week=tools::toTitleCase(Week))

接下来,我们可以通过列号轻松地进行聚合,因此不需要使用名称。

aggregate(list(Time=Test[, 5]), list(Week=Test[, 3]), mean)
#       Week Time
# 1   Friday  5.0
# 2 Thursday  4.5

如果手动硬编码列索引存在问题,我们可以使用agrep,通过字符串距离匹配来识别最相似的列名的索引。
c_tcalc <- agrep('timeofcalculate', names(Test))
c_week <- agrep('week', names(Test))

aggregate(list(Time=Test[, c_tcalc]), list(Week=Test[, c_week]), mean)
#       Week Time
# 1   Friday  5.0
# 2 Thursday  4.5

数据:

Test <- structure(list(date1 = structure(c(18932, 18932, 18932, 18932
), class = "Date"), date2 = structure(c(18922, 18922, 18928, 
18930), class = "Date"), Week = c("Friday", "Friday", "Thursday", 
"Thursday"), Category = c("FDE", "FDE", "FDE", "FDE"), TimeofCalculate = c(4, 
6, 6, 3)), class = "data.frame", row.names = c(NA, -4L))

1

也许我们可以利用 tidyselect::matches

library(dplyr)

nms <- c('TimeofCalculate|Timeofcalculate|Timeofcalculâte')

#alternative one
Test %>%
  group_by(Week = tools::toTitleCase(Week)) %>% 
  summarise(across(matches(nms), mean), .groups = 'drop')
#> # A tibble: 2 × 2
#>   Week     TimeofCalculate
#>   <chr>              <dbl>
#> 1 Friday               5  
#> 2 Thursday             4.5

#using a purrr style lambda
Test %>%
  group_by(Week = tools::toTitleCase(Week)) %>% 
  summarise(across(matches(nms), ~mean(., na.rm = TRUE)), .groups = 'drop')
#> # A tibble: 2 × 2
#>   Week     TimeofCalculate
#>   <chr>              <dbl>
#> 1 Friday               5  
#> 2 Thursday             4.5

#this will also work

Test %>%
  group_by(Week = tools::toTitleCase(Week)) %>%
  summarise(across(any_of(c("Timeofcalculate", "TimeofCalculate", "Timeofcalculâte")), ~ mean(., na.rm = TRUE)), .groups = "drop")

本文档由 reprex包 (v2.0.1) 于2021年12月26日创建。


一个疑问:我已经使用了 summarise(Time=mean(Timeofcalculate), .groups = 'drop'),这里的 Time 是标题,但在你的代码中却没有了。我发现你不能使用 summarise(Time=across(matches(nms), mean), .groups = 'drop'),那么我该如何调整呢?你知道吗?再次感谢! - Antonio
因为我们只知道将选择一个列,所以我们可以像这样使用.names参数:summarise(across(matches(nms), mean, .names = 'Time'), .groups = 'drop')。这是你要找的吗? - jpdugo17

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接