1

我有一个 df 约 10000obs,24 个变量。该df的样本将是:

A <- c("EA32", "EA32", "EA32", "EA67", "EA67", "EA67", "EA67",
       "EA34", "EA34", "EA34", "EA69", "EA69", "EA69", "EA69")
B <- c("c1", "c2", "c3", "c1", "c2", "c1", "c2",
       "c2", "c2", "c1", "c2", "c2", "c3", "c3")
C <- c("USB", "UA", "UA", "UD", "UE", "USB", "UA",
       "UA", "USB", "UZ", "UA", "UE", "USB", "UE")
df <- data.frame(A,B,C)

我很想生成一个看起来像这样的 df2:

B    EA32   EA67  EA34  EA69
c1   USB    USB   NA    NA
c1   NA     NA    UZ    NA
c1   NA     UD    NA    NA
c2   UA     UA    UA    UA
c2   NA     UE    NA    UE
c2   NA     NA    USB   NA
c3   UA     NA    NA    NA
c3   NA     NA    NA    USB
c3   NA     NA    NA    UE

我试过了:

df2 <- df %>% pivot_wider(names_from = A, values_from = C)

但这给了我三行和 5 列,其中来自 df$C 的数据分组到 c("","") 中,然后我尝试使用单独的行进行分离:

df2 <- df %>% tidyr::separate_rows(df, EA32, sep = ",") 
df2 <- df2 %>% tidyr::separate_rows(df, EA67, sep = ",") ...

但我必须为每一列编写每一行代码,总共有 24 列,这变得非常乏味,并且不会生成我需要的 df2 的正确输出。任何帮助提出从 df 到 df2 的代码将不胜感激。

谢谢!

4

4 回答 4

1

我不认为你的输出是正确的,它可以进一步缩小,使用 reshape2

library(reshape2)
dcast(df,B+C~A,value.var="C")

   B   C EA32 EA34 EA67 EA69
1 c1  UD <NA> <NA>   UD <NA>
2 c1 USB  USB <NA>  USB <NA>
3 c1  UZ <NA>   UZ <NA> <NA>
4 c2  UA   UA   UA   UA   UA
5 c2  UE <NA> <NA>   UE   UE
6 c2 USB <NA>  USB <NA> <NA>
7 c3  UA   UA <NA> <NA> <NA>
8 c3  UE <NA> <NA> <NA>   UE
9 c3 USB <NA> <NA> <NA>  USB
于 2021-10-12T06:53:16.173 回答
0

您的问题是,对于某些A值,您有重复B值,因此您首先需要创建一个基于 的附加 ID 列A,然后complete是 tibble,然后您可以pivot_wider

library(tidyverse)
df %>%
  group_by(A) %>%
  mutate(id_col = 1:n()) %>%
  ungroup() %>%
  complete(id_col, A, B) %>%
  pivot_wider(names_from = A, values_from = C) %>%
  select(-id_col)

这使:

# A tibble: 12 x 5
   B     EA32  EA34  EA67  EA69 
   <chr> <chr> <chr> <chr> <chr>
 1 c1    USB   NA    UD    NA   
 2 c2    NA    UA    NA    UA   
 3 c3    NA    NA    NA    NA   
 4 c1    NA    NA    NA    NA   
 5 c2    UA    USB   UE    UE   
 6 c3    NA    NA    NA    NA   
 7 c1    NA    UZ    USB   NA   
 8 c2    NA    NA    NA    NA   
 9 c3    UA    NA    NA    USB  
10 c1    NA    NA    NA    NA   
11 c2    NA    NA    UA    NA   
12 c3    NA    NA    NA    UE 
于 2021-10-12T06:45:04.927 回答
0

使用tidyrdplyr

library(dplyr)
library(tidyr)
df %>%
  mutate(D=rownames(.)) %>%
  pivot_wider(names_from=A, values_from=C, values_fill=NA) %>%
  arrange(B) %>%
  select(-D)

输出:

# A tibble: 14 x 5
   B     EA32  EA67  EA34  EA69 
   <chr> <chr> <chr> <chr> <chr>
 1 c1    USB   <NA>  <NA>  <NA> 
 2 c1    <NA>  UD    <NA>  <NA> 
 3 c1    <NA>  USB   <NA>  <NA> 
 4 c1    <NA>  <NA>  UZ    <NA> 
 5 c2    UA    <NA>  <NA>  <NA> 
 6 c2    <NA>  UE    <NA>  <NA> 
 7 c2    <NA>  UA    <NA>  <NA> 
 8 c2    <NA>  <NA>  UA    <NA> 
 9 c2    <NA>  <NA>  USB   <NA> 
10 c2    <NA>  <NA>  <NA>  UA   
11 c2    <NA>  <NA>  <NA>  UE   
12 c3    UA    <NA>  <NA>  <NA> 
13 c3    <NA>  <NA>  <NA>  USB  
14 c3    <NA>  <NA>  <NA>  UE   
于 2021-10-12T06:47:58.987 回答
0

不完全是您的订单,但也许可行?您似乎希望将每个匹配的 B+C 组合分组到各自的行中。

df %>%
  group_by(B) %>%
  arrange(B, C) %>%
  mutate(row = cumsum(C != lag(C, 1, ""))) %>%
  ungroup() %>%
  pivot_wider( names_from = A, values_from = C)


# A tibble: 9 x 6
  B       row EA67  EA32  EA34  EA69 
  <chr> <int> <chr> <chr> <chr> <chr>
1 c1        1 UD    NA    NA    NA   
2 c1        2 USB   USB   NA    NA   
3 c1        3 NA    NA    UZ    NA   
4 c2        1 UA    UA    UA    UA   
5 c2        2 UE    NA    NA    UE   
6 c2        3 NA    NA    USB   NA   
7 c3        1 NA    UA    NA    NA   
8 c3        2 NA    NA    NA    UE   
9 c3        3 NA    NA    NA    USB 
于 2021-10-12T06:50:08.983 回答