簡體   English   中英

將復制的數據移動到 R 中的下一列

[英]Moving replicated data in to the next columns in R

我的數據如下:

 df <- read.table(text = "MXZ 'bam' 12 'B1' 'sdr' 11 'B3' 'kar' 13 'B5' 'mmn' 13 'B7' 'bam' 14 'B4' 'kar' 17 'B1' 'bam' 10 'B6' 'zar' 11 'B8' 'mmn' 12 'B12' ", header = TRUE)

我想將復制的數據移動到下一列。 考慮到“bam”,它出現了三遍。 現在,我想將它移到下一列,它第一次出現的地方,其他復制的數據將出現在其他列中。 當復制的數據被移動到其他列時,它們將從列中刪除,得到以下表:

 df <- read.table(text = " MXZ X1 Z1 X2 Z2 'bam' 12 'B1' 14 'B4' 10 'B6' 'sdr' 11 'B3' NA NA NA NA 'kar' 13 'B5' 17 'B1' NA NA 'mmn' 13 'B7' 12 'B12' NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 'zar' 11 'B8' NA NA NA NA NA NA NA NA NA NA NA ", header = TRUE) > df

我知道我需要提供我的解決方案,但我無法找到解決方案。

一種可能的方法是在tidyr中使用unnest_wider() 取消嵌套時,列表項的名稱將自動用作列名。

我相信有更好的方法來構建records列表,但目前,這是我能想到的最好的方法。

library(dplyr)
library(tidyr)

df1 <- df %>%
    group_by(M) %>%
    # convert column X and Z to a list column with each element named as
    # X_1,X_2,... and Z_1,Z_2, ...
    summarise(records = list(
        append(
            as.list(X) %>% setNames(paste0("X_",seq_along(X))),
            as.list(Z) %>% setNames(paste0("Z_",seq_along(Z)))
        ))
    ) %>%
   # when unnested, the name for a list element will be automated applied the the column name
    unnest_wider(records)
> df1

# A tibble: 5 x 7
  M       X_1   X_2   X_3 Z_1   Z_2   Z_3  
  <chr> <int> <int> <int> <chr> <chr> <chr>
1 bam      12    14    10 B1    B4    B6   
2 kar      13    17    NA B5    B1    NA   
3 mmn      13    12    NA B7    B12   NA   
4 sdr      11    NA    NA B3    NA    NA   
5 zar      11    NA    NA B8    NA    NA   

這是一個選項,通過循環遍歷數據集的names ,除了第一個,按“M”分組, summarise在一個list ,使用unnest_wider ,通過連接list的元素reduce到單個 data.frame,然后right_join與原始數據集'M'並重新排序數據集的列

library(purrr)
library(tidyr)
library(dplyr)
library(stringr)
map(names(df)[-1], ~ df %>%
       dplyr::select(M, .x) %>% 
       group_by(M) %>%
       summarise(!! .x := list(as.list(!! rlang::sym(.x)) %>% 
                     set_names(str_c(.x, seq_along(.)))))  %>% 
       unnest_wider(.x)) %>% 
  reduce(full_join, by = 'M') %>% 
  right_join(df1 %>%
                dplyr::select(M)) %>% 
  dplyr::select(M, order(str_remove(names(.)[-1], "\\D+")) + 1)
# A tibble: 9 x 7
#  M        X1 Z1       X2 Z2       X3 Z3   
#  <fct> <int> <fct> <int> <fct> <int> <fct>
#1 bam      12 B1       14 B4       10 B6   
#2 sdr      11 B3       NA <NA>     NA <NA> 
#3 kar      13 B5       17 B1       NA <NA> 
#4 mmn      13 B7       12 B12      NA <NA> 
#5 <NA>     NA <NA>     NA <NA>     NA <NA> 
#6 <NA>     NA <NA>     NA <NA>     NA <NA> 
#7 <NA>     NA <NA>     NA <NA>     NA <NA> 
#8 zar      11 B8       NA <NA>     NA <NA> 
#9 <NA>     NA <NA>     NA <NA>     NA <NA> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM