Разделение одного вектора столбца на разные столбцы, в соответствии с первыми символами

#r #loops #indexing

#r #циклы #индексирование

Вопрос:

У меня есть такой вектор столбцов, но с 15000 строками:

 df <- data.frame(c("aaa000_587","aaa000_201","aaa000_577","axx005_449","axx005_497", "bbb101_587", "bbb101_664"))

colnames(df) <- c("0")
 

Я хотел бы идентифицировать первые 6 буквенно-цифровых символов и сгруппировать их в одну строку, например:

0 1 2
aaa000_587 aaa000_201 aaa000_577
axx005_449 axx005_449
bbb101_587 bbb101_664

Первые шесть символов — это то, что определяет идентификатор субъекта, поэтому я хотел бы иметь идентификатор каждого участника, независимо от того, что идет после подчеркивания, в одной строке. Ожидается, что каждая строка будет содержать разное количество столбцов.

Я считаю, что это может работать с циклом for и if. Я заблокирован и не могу заставить какой-либо код работать. пожалуйста, помогите! Спасибо!

Ответ №1:

Вот вариант с substr и pivot_wider

 library(dplyr)
library(tidyr)
library(data.table)
df %>%
      mutate(val = substr(`0`, 1, 6), rn = rowid(val)) %>% 
      pivot_wider(names_from = rn, values_from = `0`) %>%
      select(-val)
 

-вывод

 # A tibble: 3 x 3
#   `1`        `2`        `3`       
#    <chr>      <chr>      <chr>     
#1 aaa000_587 aaa000_201 aaa000_577
#2 axx005_449 axx005_497 <NA>      
#3 bbb101_587 bbb101_664 <NA>  
 

Ответ №2:

В базе R вы могли бы сделать:

 reshape(transform(df, time = ave(`0`,id<-substr(`0`, 1, 6), FUN=seq_along), id=id), dir="wide")[-1]

        X0.1       X0.2       X0.3
1 aaa000_587 aaa000_201 aaa000_577
4 axx005_449 axx005_497       <NA>
6 bbb101_587 bbb101_664       <NA>
 

Это можно разбить на:

 df$id <- substr(df[,1], 1, 6)
df$time <- ave(df[,1],df$id, FUN=seq_along)
reshape(df, dir='wide')[-1]
         0.1        0.2        0.3
1 aaa000_587 aaa000_201 aaa000_577
4 axx005_449 axx005_497       <NA>
6 bbb101_587 bbb101_664       <NA>
 

Ответ №3:

data.table Вариант с использованием dcast

 dcast(
  dt[
    ,
    c("N", "q") := list(seq(.N), substr(`0`, 1, 6)),
    substr(`0`, 1, 6)
  ],
  q ~ N,
  value.var = "0"
)[, -"q"]
 

дает

             1          2          3
1: aaa000_587 aaa000_201 aaa000_577
2: axx005_449 axx005_497       <NA>
3: bbb101_587 bbb101_664       <NA>
 

Данные

 > dput(dt)
structure(list(`0` = c("aaa000_587", "aaa000_201", "aaa000_577", 
"axx005_449", "axx005_497", "bbb101_587", "bbb101_664")), row.names = c(NA,
-7L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x00000000044a1ef0>)