首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用dplyr的合并函数和group_by()来为每个人创建一行,并填写所有值?

如何使用dplyr的合并函数和group_by()来为每个人创建一行,并填写所有值?
EN

Stack Overflow用户
提问于 2022-05-31 20:35:22
回答 2查看 197关注 0票数 2

我正在尝试使用coalesce()来生成每一个参与者有他们的名字和分数的一行。参与者有3次机会填写他们的数据,大多数只有一次(而那些多次输入的总是输入相同的数据)。所以我的数据看起来是:

代码语言:javascript
运行
复制
library(dplyr)

test_dataset <- tibble(name = c("justin", "justin", "justin", "corey", "corey", "corey", "sib", "sib", "sib", "kate", "kate", "kate"),
                       score1 = c(NA_real_, NA_real_, 1, 2, NA_real_, NA_real_, 2, NA_real_, 2, NA_real_, NA_real_ , NA_real_),
                       score2 = c(NA_real_, 7, NA_real_, 5, NA_real_, NA_real_, 9, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_))

我想让它看起来像:

代码语言:javascript
运行
复制
library(dplyr)

answer <- tibble(name = c("justin", "corey", "sib", "kate"),
                       score1_true = c(1, 2, 2, NA),
                       score2_true = c(7, 5, 9, NA))

我尝试了下面的解决方案,它确实给了我“真”的分数,但是它分散在12行(每人3行)上,而不是4行(每人1行):

代码语言:javascript
运行
复制
library(dplyr)

test_dataset %>%
  dplyr::group_by(name) %>%
  mutate(across(c(starts_with("score")), .fns = list(true = ~coalesce(.))))
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-31 20:40:08

我们可以根据NA元素重新排序这些值,然后将第一行切片

代码语言:javascript
运行
复制
library(dplyr)
test_dataset %>% 
  group_by(name) %>%
  dplyr::mutate(across(starts_with('score'), 
   ~ .x[order(is.na(.x))])) %>% 
  slice_head(n = 1) %>% 
  ungroup

-output

代码语言:javascript
运行
复制
# A tibble: 4 × 3
  name   score1 score2
  <chr>   <dbl>  <dbl>
1 corey       2      5
2 justin      1      7
3 kate       NA     NA
4 sib         2      9

或者另一种选择是在重新安排之后使用complete.cases

代码语言:javascript
运行
复制
test_dataset %>% 
  group_by(name) %>%
  dplyr::mutate(across(starts_with('score'), 
   ~ .x[order(is.na(.x))])) %>% 
  filter(complete.cases(across(starts_with('score')))|row_number() == 1) %>%
   ungroup

-output

代码语言:javascript
运行
复制
# A tibble: 4 × 3
  name   score1 score2
  <chr>   <dbl>  <dbl>
1 justin      1      7
2 corey       2      5
3 sib         2      9
4 kate       NA     NA
票数 3
EN

Stack Overflow用户

发布于 2022-05-31 20:45:34

您可以使用fill(),然后使用arrange()分数和使用slice_head()

代码语言:javascript
运行
复制
test_dataset %>% 
  group_by(name) %>%
  fill(score1, score2) %>%
  arrange(score1, score2) %>%
  slice_head(n=1)

输出:

代码语言:javascript
运行
复制
  name   score1_true score2_true
  <chr>        <dbl>       <dbl>
1 justin           1           7
2 corey            2           5
3 sib              2           9
4 kate            NA          NA

多亏了@M.Viking,更简洁/更好的版本:

fill()中的

  • 使用.direction="up"选项

代码语言:javascript
运行
复制
test_dataset %>% 
  group_by(name) %>%
  fill(score1, score2, .direction="up") %>%
  slice_head(n=1)
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72453849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档