【问题标题】:Adding new, combined values to existing dataframe in R向 R 中的现有数据框添加新的组合值
【发布时间】:2018-04-26 17:43:28
【问题描述】:

这是原始数据帧的近似值。在原始版本中,列数比此处显示的要多得多。

id  init_cont  family  description  value
1   K          S       impacteach   1
1   K          S       impactover   3
1   K          S       read         2
2   I          S       impacteach   2
2   I          S       impactover   4
2   I          S       read         1
3   K          D       impacteach   3
3   K          D       impactover   5
3   K          D       read         3

我想结合 Impacteach 和 Impactover 的值来生成一个平均值,即所谓的 Impact。我希望决赛桌如下所示:

id  init_cont  family  description  value
1   K          S       impact       2
1   K          S       read         2
2   I          S       impact       3
2   I          S       read         1
3   K          D       impact       4
3   K          D       read         3

我无法弄清楚如何生成此表。但是,我已经能够创建一个如下所示的数据框:

id  description  value
1   impact       2
1   read         2
2   impact       3
2   read         1
3   impact       4
3   read         3

对我来说,获取这些新值并将它们添加到原始数据框中的最佳方法是什么?我还需要删除原始数据框中的原始值(如 Impacteach 和 Impactover)。我宁愿修改原始数据框,而不是创建一个全新的数据框,因为原始数据框有很多列。

如果有用的话,这是我用来创建较短数据帧的代码摘要,该数据帧具有影响力作为 Impacteach 和 Impactover 的组合:

df %<%
  mutate(newdescription = case_when(description %in% c("impacteach", "impactoverall") ~ "impact", TRUE ~ description)) %<% 
  group_by(id, newdescription) %<%
  summarise(value = mean(as.numeric(value)))

【问题讨论】:

  • 你说你有更多的专栏是什么意思?您是否有更多类似于description 或只是value 的列?

标签: r tidyverse dplyr


【解决方案1】:

如果您先更改 description 列以便将其包含在分组中会怎样:

df %>% 
    mutate(description = substr(description, 1, 6)) %>%
    group_by(id, init_cont, family, description) %>% 
    summarise(value = mean(value))

# A tibble: 6 x 5
# Groups:   id, init_cont, family [?]
#      id init_cont family description value
#   <int> <chr>     <chr>  <chr>       <dbl>
# 1     1 K         S      impact         2.
# 2     1 K         S      read           2.
# 3     2 I         S      impact         3.
# 4     2 I         S      read           1.
# 5     3 K         D      impact         4.
# 6     3 K         D      read           3.

【讨论】:

    【解决方案2】:

    您只需要修改您的group_by 语句。试试group_by(id, init_cont, family)

    因为您的 id 似乎已经映射到 init_cont 和 family,所以添加这些值不会改变您的汇总结果。这样您就拥有了所有您想要的列,而无需额外的工作。

    如果您有 很多 列,您可以尝试以下代码。本质上,使用汇总数据对原始数据执行left_join,但使用. 执行此操作以不存储新数据帧。然后,一旦加入(通过我们在适当位置修改的 id 和描述),您将有两个值列,应以 .x 和 .y 开头,删除原始值,然后使用 distinct 消除重复的“影响”列。

    df %>% 
      mutate(description = case_when(description %in% c("impacteach", "impactoverall") ~ "impact", TRUE ~ description)) %>%
      left_join(. %>%
                  group_by(id, description)
                  summarise(value = mean(as.numeric(value))
                ,by=c('id','description')) %>%
      select(-value.x) %>%
      distinct()
    

    【讨论】:

    • 我的列比这里显示的多得多。有没有一种简单的方法可以为超过 100 列执行此操作?
    • select(-value.x) 是什么意思?此外,“by=c”之前的逗号会导致错误。
    • 否定选择删除一列。对于这个错误,我很抱歉,您没有提供可重现的示例,所以我无法测试代码
    【解决方案3】:

    gsub 可用于替换包含imactdescription 作为影响,然后dplyr 包中的group_by 将有助于总结价值。

    df %>% group_by(id, init_cont, family, 
            description = gsub("^(impact).*","\\1", description)) %>%
      summarise(value = mean(value))
    
    # # A tibble: 6 x 5
    # # Groups: id, init_cont, family [?]
    #      id init_cont family description value
    #   <int> <chr>     <chr>  <chr>       <dbl>
    # 1     1 K         S      impact       2.00
    # 2     1 K         S      read         2.00
    # 3     2 I         S      impact       3.00
    # 4     2 I         S      read         1.00
    # 5     3 K         D      impact       4.00
    # 6     3 K         D      read         3.00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-21
      • 2020-11-08
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多