基于group_by将轴旋转得更宽

pu82cl6c  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(110)

我有一个数据框,我想根据record_id和LOC中的匹配值来pivot_wide,所以record_id 1的两行都有Loc = LUC。所以我想合并这两行的信息,这样每个record_id和Loc组合只存在一行

df <- read.table(text = 
"  record_id   found   order   delivered   Loc coord   A   B   C   D   E   F   G
1   1   1/1/18  1/2/18  LUC A:123   A   A1  TR1 1   1   A   BC1
1   1   1/1/18  1/3/18  LUC B:124   B   A2  TR2 1   1   B   BC2
2   1   1/1/18  1/4/18  AMZ C:125   C   A3  TR3 2   2   C   BC3
3   NA  1/1/18  1/5/18  FR  A:126   A   A4  TR4 3   3   A   BC4
4   NA  1/1/18  1/6/18  FR  B:127   B   A5  TR5 4   4   B   BC5
5   1   1/1/18  1/7/18  LUC A:128   A   A6  TR6 5   5   A   BC6
5   1   1/1/18  1/8/18  FR  A:129   A   A7  TR7 5   5   A   BC7", header = TRUE)

字符串
所需产量

record_id   found   order   delivered   Loc coord   A   B   C   D   E   F   G   coord_2 A_2 B_2 C_2 D_2 E_2 F_2 G_2
1   1   1/1/18  1/2/18  LUC A:123   A   A1  TR1 1   1   A   BC1 B:124   B   A2  TR2 1   1   B   BC2
2   1   1/1/18  1/4/18  AMZ C:125   C   A3  TR3 2   2   C   BC3 NA  NA  NA  NA  NA  NA  NA  NA
3   NA  1/1/18  1/5/18  FR  A:126   A   A4  TR4 3   3   A   BC4 NA  NA  NA  NA  NA  NA  NA  NA
4   NA  1/1/18  1/6/18  FR  B:127   B   A5  TR5 4   4   B   BC5 NA  NA  NA  NA  NA  NA  NA  NA
5   1   1/1/18  1/7/18  LUC A:128   A   A6  TR6 5   5   A   BC6 NA  NA  NA  NA  NA  NA  NA  NA
5   1   1/1/18  1/8/18  FR  A:129   A   A7  TR7 5   5   A   BC7 NA  NA  NA  NA  NA  NA  NA  NA


我试过了,但是不管用

df %>%
  group_by(record_id, Loc) %>%
  pivot_wider(names_from = c(record_id, Loc),
              values_from = c(coord:G))

gorkyyrv

gorkyyrv1#

df %>%
  mutate(group_index = row_number(), .by = c(record_id, Loc)) %>%
  pivot_wider(names_from = group_index, values_from = coord:G, names_vary = "slowest") %>%
  rename_with(~sub("_1", "", .x), ends_with("_1")) # H/T @andre-wildberg

字符串
结果

# A tibble: 7 × 21
  record_id found order  delivered Loc   coord A     B     C         D     E F     G     coord_2 A_2   B_2   C_2     D_2   E_2 F_2   G_2  
      <int> <int> <chr>  <chr>     <chr> <chr> <chr> <chr> <chr> <int> <int> <chr> <chr> <chr>   <chr> <chr> <chr> <int> <int> <chr> <chr>
1         1     1 1/1/18 1/2/18    LUC   A:123 A     A1    TR1       1     1 A     BC1   NA      NA    NA    NA       NA    NA NA    NA   
2         1     1 1/1/18 1/3/18    LUC   NA    NA    NA    NA       NA    NA NA    NA    B:124   B     A2    TR2       1     1 B     BC2  
3         2     1 1/1/18 1/4/18    AMZ   C:125 C     A3    TR3       2     2 C     BC3   NA      NA    NA    NA       NA    NA NA    NA   
4         3    NA 1/1/18 1/5/18    FR    A:126 A     A4    TR4       3     3 A     BC4   NA      NA    NA    NA       NA    NA NA    NA   
5         4    NA 1/1/18 1/6/18    FR    B:127 B     A5    TR5       4     4 B     BC5   NA      NA    NA    NA       NA    NA NA    NA   
6         5     1 1/1/18 1/7/18    LUC   A:128 A     A6    TR6       5     5 A     BC6   NA      NA    NA    NA       NA    NA NA    NA   
7         5     1 1/1/18 1/8/18    FR    A:129 A     A7    TR7       5     5 A     BC7   NA      NA    NA    NA       NA    NA NA    NA

r1zhe5dt

r1zhe5dt2#

您的问题涉及将长格式 Dataframe 转换为宽格式 Dataframe ,合并具有相同'record_id'和'Loc'的行。下面是使用R中的dplyrtidyverse包的解决方案。
首先,您需要创建一个额外的分组变量,用于定义每个组中的唯一组合。这可以使用dplyr中的group_indices()函数来实现。之后,您可以使用tidyverse中的pivot_wider()函数来转换 Dataframe 。
下面是实现这一点的R代码:

library(dplyr)
library(tidyverse)

df <- df %>%
  group_by(record_id, Loc) %>%
  mutate(group_index = group_indices()) %>%
  ungroup()

df_wide <- df %>%
  pivot_wider(names_from = group_index, values_from = coord:G, 
              names_glue = "{.value}_{.name}")

字符串
group_indices()函数为每个组创建一个唯一的索引,pivot_wider()函数使用这些索引在宽格式数据框中创建新的列名。
您可能需要处理缺失值,或者决定在同一组合有多个值时应如何处理。这可以通过在pivot_wider()函数中指定values_fnvalues_fill参数来完成。例如,要使用每个组中的第一个非NA值并使用NA填充缺失值,可以使用values_fn = list(coord:G = ~first(na.omit(.)))values_fill = NA
此解决方案假设您希望在同一'record_id'和'Loc'有多个条目的情况下保留第一个值。如果您想使用不同的策略,则需要在values_fn参数中指定它。

0tdrvxhp

0tdrvxhp3#

使用unnest_widerrelocate只是为了匹配给定的顺序,但实际上并不是必需的。使用rename_with更正列名

library(dplyr)
library(tidyr)

df %>% 
  summarize(across(found:delivered, ~ .x[1]), 
            across(coord:G, list), .by = c(record_id, Loc)) %>% 
  unnest_wider(coord:G, names_sep="_") %>% 
  relocate(matches(".*_[2-9]|.*_[1-9][0-9]"), 
    .after = ends_with("_1")) %>% 
  rename_with(~ sub("_1", "", .x), ends_with("_1")) %>% 
  print(Inf)
# A tibble: 6 × 21
  record_id Loc   found order  delivered coord A     B     C         D 
      <int> <chr> <int> <chr>  <chr>     <chr> <chr> <chr> <chr> <int> 
1         1 LUC       1 1/1/18 1/2/18    A:123 A     A1    TR1       1 
2         2 AMZ       1 1/1/18 1/4/18    C:125 C     A3    TR3       2 
3         3 FR       NA 1/1/18 1/5/18    A:126 A     A4    TR4       3 
4         4 FR       NA 1/1/18 1/6/18    B:127 B     A5    TR5       4 
5         5 LUC       1 1/1/18 1/7/18    A:128 A     A6    TR6       5 
6         5 FR        1 1/1/18 1/8/18    A:129 A     A7    TR7       5 
      E F     G     coord_2 A_2   B_2   C_2     D_2   E_2 F_2   G_2  
  <int> <chr> <chr> <chr>   <chr> <chr> <chr> <int> <int> <chr> <chr>
1     1 A     BC1   B:124   B     A2    TR2       1     1 B     BC2  
2     2 C     BC3   NA      NA    NA    NA       NA    NA NA    NA   
3     3 A     BC4   NA      NA    NA    NA       NA    NA NA    NA   
4     4 B     BC5   NA      NA    NA    NA       NA    NA NA    NA   
5     5 A     BC6   NA      NA    NA    NA       NA    NA NA    NA   
6     5 A     BC7   NA      NA    NA    NA       NA    NA NA    NA

字符串

相关问题