【问题标题】:Combining and duplicating rows based on a condition根据条件组合和复制行
【发布时间】:2020-10-20 17:05:47
【问题描述】:

我正在寻找一种优雅的解决方案,用于根据条件组合、复制和改变行:

在我的示例中,我想组合 x = 1 和 x = 2,然后复制这些行。然后将每个子集变异回其原始分类。

数据

df <- tibble(x = c(1,1,1,2,2,2,3,4,5,6), 
         y = c(11,12,13,14,15,16,17,18,19,20), 
         z = c(21,22,23,24,25,26,27,28,29,30))
       x     y     z
   <dbl> <dbl> <dbl>
 1     1    11    21
 2     1    12    22
 3     1    13    23
 4     2    14    24
 5     2    15    25
 6     2    16    26
 7     3    17    27
 8     4    18    28
 9     5    19    29
10     6    20    30

当前解决方案

当 x 在 1 或 2 时合并行并将它们存储为 1

df <- df %>%
  mutate(x = ifelse(x %in% c(1,2), 1, x))

x 的过滤器为 1 并变异为 2。将其存储为子集

df_temp <- df %>%
  filter(x == 1) %>%
  mutate(x = 2)

将行绑定回来

df <- rbind(df,df_temp)

期望的输出

       x     y     z
   <dbl> <dbl> <dbl>
 1     1    11    21
 2     1    12    22
 3     1    13    23
 4     1    14    24
 5     1    15    25
 6     1    16    26
 7     3    17    27
 8     4    18    28
 9     5    19    29
10     6    20    30
11     2    11    21
12     2    12    22
13     2    13    23
14     2    14    24
15     2    15    25
16     2    16    26

我认为第一步可以跳过。 separate_rows() 如果我将它们与分隔符结合起来,可能会在这里解决问题,但我想避免这种情况。

正在寻找 dplyr 解决方案。

编辑 2:

如果我们将上面的数据简化为:

df <- tibble(x = c(1,1,2,2,2,3,4,5,6), 
             y = c(11,12,14,15,16,17,18,19,20), 
             z = c(21,22,24,25,26,27,28,29,30))

其中 x = 1 和 x = 2 的行数不同。过滤和反转 y 和 z 不再给出正确的解决方案。

预期结果

      x     y     z
   <dbl> <dbl> <dbl>
 1     1    11    21
 2     1    12    22
 3     1    14    24
 4     1    15    25
 5     1    16    26
 6     2    14    24
 7     2    15    25
 8     2    16    26
 9     2    11    21
10     2    12    22
11     3    17    27
12     4    18    28
13     5    19    29
14     6    20    30

【问题讨论】:

  • 1:2 范围内的行数超过 2 行时,您能否扩展您的示例和预期输出?
  • @RonakShah 展开。

标签: r dplyr


【解决方案1】:

你可以试试

df %>% 
  full_join(filter(df, x %in% 1:2) %>% complete(x, y)) 
# A tibble: 5 x 2
      x     y
  <dbl> <dbl>
1     1     6
2     2     7
3     3     8
4     1     7
5     2     6

当包含z 列时,必须完成嵌套列yz 之类的

df %>% 
  full_join(filter(df, x %in% 1:2) %>% 
              complete(x, nesting(y, z))) %>% 
  arrange(x)
# A tibble: 16 x 3
       x     y     z
   <dbl> <dbl> <dbl>
 1     1    11    21
 2     1    12    22
 3     1    13    23
 4     1    14    24
 5     1    15    25
 6     1    16    26
 7     2    14    24
 8     2    15    25
 9     2    16    26
10     2    11    21
11     2    12    22
12     2    13    23
13     3    17    27
14     4    18    28
15     5    19    29
16     6    20    30

【讨论】:

  • 谢谢。这在我们有两列时有效。我在示例中添加了另一列 z,并提供了预期的输出。如果你能再看看,不胜感激
【解决方案2】:

您可以filterx 为 1 或 2 的行,反转 yz 列并将数据绑定回原始数据框。

library(dplyr)

df %>%
  filter(x %in% 1:2) %>%
  mutate(across(y:z, rev)) %>%
  #In old dplyr use mutate_at
  #mutate_at(vars(y:z), rev) %>%
  bind_rows(df)


# A tibble: 16 x 3
#       x     y     z
#   <dbl> <dbl> <dbl>
# 1     1    16    26
# 2     1    15    25
# 3     1    14    24
# 4     2    13    23
# 5     2    12    22
# 6     2    11    21
# 7     1    11    21
# 8     1    12    22
# 9     1    13    23
#10     2    14    24
#11     2    15    25
#12     2    16    26
#13     3    17    27
#14     4    18    28
#15     5    19    29
#16     6    20    30

【讨论】:

  • 感谢您的回答。这可能又不是一个好例子,因为 x = 1x = 2 都具有相同的行数 (3)。如果他们不这样做,假设删除第 3 行,我们最终会得到 4 行 x =1 和 6 行 x = 2。最终结果应该具有相同的行数。我可以再次更改我的示例。
猜你喜欢
  • 2021-12-31
  • 2019-11-03
  • 2021-10-31
  • 1970-01-01
  • 2018-07-11
  • 2017-08-20
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
相关资源
最近更新 更多