我有一个包含以下列的数据框:
> colnames(my.dataframe)
[1] "id" "firstName" "lastName"
[4] "position" "jerseyNumber" "currentTeamId"
[7] "currentTeamAbbreviation" "currentRosterStatus" "height"
[10] "weight" "birthDate" "age"
[13] "birthCity" "birthCountry" "rookie"
[16] "handednessShoots" "college" "twitter"
[19] "currentInjuryDescription" "currentInjuryPlayingProbability" "teamId"
[22] "teamAbbreviation" "fg2PtAtt" "fg3PtAtt"
[25] "fg2PtMade" "fg3PtMade" "ftMade"
[28] "fg2PtPct" "fg3PtPct" "ftPct"
[31] "ast" "tov" "offReb"
[34] "foulsDrawn" "blkAgainst" "plusMinus"
[37] "minSeconds"
这是我的无效代码:
my.dataframe %>%
dplyr::group_by(id) %>%
dplyr::summarise_at(vars(firstName:currentInjuryPlayingProbability), funs(min), na.rm = TRUE) %>%
dplyr::summarise_at(vars(fg2PtAtt:minSeconds), funs(sum), na.rm = TRUE) %>%
vars(), funs(min), na.rm = TRUE) %>%
dplyr::summarise(teamId = paste(teamId), teamAbbreviation = paste(teamAbbreviation))
首先,我按id分组(尽管它被称为id,但在我的数据框中不是唯一的列)。在直到currentInjuryPlayingProbability之前的接下来的19列中,这些列在按ID分组时始终是相同的,因此我使用min
函数来汇总/获取值。
接下来,我要总结从fg2PtAtt
到末尾的所有列,并给出平均值(这些列都是数字/整数)。
最后,对于teamId和teamAbbreviation列(在grouped_by id时不相同),我想将它们粘贴到单个字符串中,每个字符串都具有摘要。
我的方法行不通,因为我认为我不能先调用summarise_at,再调用另一个summarise_at,再调用一个summarise。到第二个summarise_at调用时,第一个summarise_at已经删除了要汇总的列
感谢您提供任何帮助!我将在不久的将来更新我的数据框的一部分,以便对其进行测试。
编辑:
dput(my.dataframe)
structure(list(id = c(10138L, 9466L, 9360L, 9360L), firstName = c("Alex",
"Quincy", "Luke", "Luke"), lastName = c("Abrines", "Acy", "Babbitt",
"Babbitt"), currentInjuryPlayingProbability = c(NA_character_,
NA_character_, NA_character_, NA_character_), teamId = c(96L,
84L, 91L, 92L), teamAbbreviation = c("OKL", "BRO", "ATL", "MIA"
), fg2PtAtt = c(70L, 73L, 57L, 2L), fg3PtAtt = c(221L, 292L,
111L, 45L), minSeconds = c(67637L, 81555L, 34210L, 8676L)), row.names = c(NA,
-4L), class = c("tbl_df", "tbl", "data.frame"))
my.dataframe
id firstName lastName currentInjuryPlayingProbability teamId teamAbbreviation fg2PtAtt fg3PtAtt minSeconds
<int> <chr> <chr> <chr> <int> <chr> <int> <int> <int>
1 10138 Alex Abrines <NA> 96 OKL 70 221 67637
2 9466 Quincy Acy <NA> 84 BRO 73 292 81555
3 9360 Luke Babbitt <NA> 91 ATL 57 111 34210
4 9360 Luke Babbitt <NA> 92 MIA 2 45 8676
这是一个简短的示例,只有9列,但有足够的数据来突出问题所在。结果数据框应如下所示:
id firstName lastName currentInjuryPlayingProbability teamId teamAbbreviation fg2PtAtt fg3PtAtt minSeconds
<int> <chr> <chr> <chr> <chr> <chr> <int> <int> <int>
1 10138 Alex Abrines <NA> 96 OKL 70 221 67637
2 9466 Quincy Acy <NA> 84 BRO 73 292 81555
3 9360 Luke Babbitt <NA> 91, 92 ATL, MIA 57 156 42886
答案 0 :(得分:4)
我认为这是完成此特定任务的最简单方法,至少与我所见过的一些类似map2
/ reduce
解决方案相比。
第一点是,如果您使用min
来获取值,因为您认为分组变量的每个值都应该相同,则只需将其添加到分组中即可。然后它会自动保存。
第二个是您可以使用{}
来将%>%
的LHS自动放置到RHS的第一个参数中。这样一来,您就可以应用不同的转换并重新组合它们。通常,您不需要这样做,因为占位符.
会为您完成此操作,但是如果占位符不是RHS的明文,则有时会需要它。 (我确定我阅读了一些描述确切规则的资源,但现在找不到)。
第三,因为您知道summarise
将删除除分组变量之外未选择的列,所以left_join
将自动使用共享的列名进行连接。
这意味着我们可以做以下事情,我认为这很干净。但是,如果转换开始变得特别复杂(例如,left_join
内有管道,我建议给最终输出的每个部分分配自己的赋值和名称,以使其更清楚。如果您还需要特别注意,想要同一列的多个摘要(如均值和标准差),因为名称会冲突。
library(tidyverse)
my_dataframe <- structure(list(id = c(10138L, 9466L, 9360L, 9360L), firstName = c("Alex", "Quincy", "Luke", "Luke"), lastName = c("Abrines", "Acy", "Babbitt", "Babbitt"), currentInjuryPlayingProbability = c(NA_character_, NA_character_, NA_character_, NA_character_), teamId = c(96L, 84L, 91L, 92L), teamAbbreviation = c("OKL", "BRO", "ATL", "MIA"), fg2PtAtt = c(70L, 73L, 57L, 2L), fg3PtAtt = c(221L, 292L, 111L, 45L), minSeconds = c(67637L, 81555L, 34210L, 8676L)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
my_dataframe %>%
group_by_at(.vars = vars(id:lastName)) %>%
{left_join(
summarise_at(., vars(teamId:teamAbbreviation), ~ str_c(., collapse = ",")),
summarise_at(., vars(fg2PtAtt:minSeconds), mean)
)}
#> Joining, by = c("id", "firstName", "lastName")
#> # A tibble: 3 x 8
#> # Groups: id, firstName [?]
#> id firstName lastName teamId teamAbbreviation fg2PtAtt fg3PtAtt
#> <int> <chr> <chr> <chr> <chr> <dbl> <dbl>
#> 1 9360 Luke Babbitt 91,92 ATL,MIA 29.5 78
#> 2 9466 Quincy Acy 84 BRO 73 292
#> 3 10138 Alex Abrines 96 OKL 70 221
#> # ... with 1 more variable: minSeconds <dbl>
由reprex package(v0.2.0)于2018-07-31创建。
答案 1 :(得分:0)
在 dplyr
1.0.2
之后更新。您可以使用 across
:
summarise(across(teamId:teamAbbreviation, ~ str_c(., collapse = ",")),
across(fg2PtAtt:minSeconds, mean)) %>%