【问题标题】:R tidyverse mutate with all combinations of subset of columns in grouped dataframeR tidyverse 与分组数据框中列子集的所有组合发生变异
【发布时间】:2020-06-03 04:14:02
【问题描述】:

我想通过 tidyverse 对分组数据帧的列子集的所有组合运行 mutate。

设置如下:

library(tidyverse)
a <- c(2018, 2019, 2020) #years
b <- c(23, 24, 25, 26) #cities
c <- c(45, 46, 47, 48, 49) #jobs
rows <- expand.grid(a, b, c) 
colnames(rows) <- c('a', 'b', 'c')
d <-  sample(c(0,1), nrow(rows), replace = TRUE)
obs <- cbind(rows, d) %>% group_by(a, b) %>% mutate(c = str_c("J", c))
wide <- obs %>% spread(c, d)

产生这个:

A grouped_df: 12 × 7
a       b   J45 J46 J47 J48 J49
2018    23  1   0   1   1   1
2018    24  0   0   1   1   0
2018    25  0   1   0   1   1
2018    26  1   0   1   1   1
2019    23  0   0   1   1   1
2019    24  0   1   0   0   1
2019    25  1   0   0   1   0
2019    26  0   1   1   1   1
2020    23  0   1   0   1   0
2020    24  1   0   1   0   1
2020    25  1   0   0   1   0
2020    26  0   1   0   0   0

数据框dataab 分组,我想找到J* 列的所有组合的总和。

我一直在参考这个 [tidyverse: Chi Square for all combinations of columns 以获得指导,但它不使用分组。

我已扩展数据框以包含所有组合

combos <- data.frame(t(combn(unique(obs$c), 2)))
data <- merge(wide, combos) %>% mutate(X1 = as.character(X1), X2 = as.character(X2))

并且 head(data, 10) 产生这个:

    a       b   J45 J46 J47 J48 J49 X1  X2
1   2018    23  1   0   1   1   1   J45 J46
2   2018    24  0   0   1   1   0   J45 J46
3   2018    25  0   1   0   1   1   J45 J46
4   2018    26  1   0   1   1   1   J45 J46
5   2019    23  0   0   1   1   1   J45 J46
6   2019    24  0   1   0   0   1   J45 J46
7   2019    25  1   0   0   1   0   J45 J46
8   2019    26  0   1   1   1   1   J45 J46
9   2020    23  0   1   0   1   0   J45 J46
10  2020    24  1   0   1   0   1   J45 J46

现在我想要 X1 列中的值和 X2 列中的值的每一行的总和。我似乎无法使 map2 或未引用的 eval 工作。我错过了什么?

感谢您的关注。

编辑:一些附加信息,我尝试过的结果和期望的输出 (@camille)。

data %&gt;% mutate(d = map2(X1, X2, sum(.x, .y))) 我明白了

Error in as_mapper(.f, ...): object '.x' not found

data %&gt;% mutate(d = sum(!!sym(X1), !!sym(X2))) 我明白了

Error in is_symbol(x): object 'X1' not found.

我不明白为什么它找不到这些元素,尤其是在 map2 的情况下。

作为输出,我需要保留分组值和列组合以及总和值(最终是加权边列表)。 @andrew_reece 和 @42- 的响应的两个输出都很好,但我很好奇为什么更直接的“在这两列中逐行添加值”行不通。

【问题讨论】:

  • 你能添加你想要与最后一个数据框对应的输出吗?
  • @Jon Spring,谢谢!

标签: r dplyr tidyr purrr


【解决方案1】:

这是一种方法:pivot_longerfilter 只剩下您想要的组合值,然后是 group_bysum

data %>%
  pivot_longer(starts_with("J"), names_to = "var", values_to = "val") %>%
  filter(var == X1 | var == X2) %>% 
  group_by(a, b, X1, X2) %>%
  summarise(combo_val = sum(val))

过滤后也可以pivot_wider,通过rowSums得到combo sums:

data %>%
  pivot_longer(starts_with("J"), names_to = "var", values_to = "val") %>%
  filter(var == X1 | var == X2) %>% 
  pivot_wider (id_cols = c(a, b, X1, X2), 
               names_from = "var", 
               values_from = "val", 
               values_fill = list(val = 0)) %>% 
  mutate(combo_val = rowSums(select(., starts_with("J")))) %>%
  select(a, b, X1, X2, combo_val)

无论哪种情况,输出都是一样的:

# A tibble: 120 x 5
       a     b X1    X2    combo_val
   <dbl> <dbl> <chr> <chr>     <dbl>
 1  2018    23 J45   J46           1
 2  2018    24 J45   J46           2
 3  2018    25 J45   J46           0
 4  2018    26 J45   J46           2
 5  2019    23 J45   J46           2
 6  2019    24 J45   J46           0
 7  2019    25 J45   J46           0
 8  2019    26 J45   J46           0
 9  2020    23 J45   J46           0
10  2020    24 J45   J46           2
# … with 110 more rows

【讨论】:

    【解决方案2】:

    我猜你想要这样的东西:

    data$sum2s <- rowSums( cbind(   #make one two-column matrix
                                 # by indexing with two other two-column matrices below
                   as.numeric( data[cbind( 1:nrow(data), match(data$X1,names(data)))]), 
                   as.numeric( data[cbind( 1:nrow(data), match(data$X2,names(data)))])
                           ) ) 
    
    
    > str(data)
    'data.frame':   120 obs. of  10 variables:
     $ a    : num  2018 2018 2018 2018 2019 ...
     $ b    : num  23 24 25 26 23 24 25 26 23 24 ...
     $ J45  : num  1 1 1 1 1 0 1 1 1 1 ...
     $ J46  : num  0 1 0 0 0 0 0 1 1 1 ...
     $ J47  : num  1 1 1 0 0 1 1 0 0 1 ...
     $ J48  : num  0 1 0 0 0 1 0 0 1 1 ...
     $ J49  : num  1 1 0 1 0 1 1 0 0 1 ...
     $ X1   : chr  "J45" "J45" "J45" "J45" ...
     $ X2   : chr  "J46" "J46" "J46" "J46" ...
     $ sum2s: num  1 2 1 1 1 0 1 2 2 2 ...
    

    它使用带有两列矩阵的索引,它允许您提取不连续的值,而不需要从同一行或列中获取所有值。见?"["

    【讨论】:

      猜你喜欢
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 2015-10-15
      相关资源
      最近更新 更多