R: чтение строк во фрейме данных и запись позиции конкретной буквы - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть фрейм данных со столбцом, содержащим строки и их оценки.Есть ли способ создать новый фрейм данных с позицией конкретной буквы в каждой строке и их оценки.Вот пример фрейма данных

df<- data.frame( string = do.call(paste0, replicate(10, sample(LETTERS, 5, TRUE), FALSE)),
             start = round(runif(5,100,500),0),
             score = round(runif(5,10,50),1)

head(df)

Это выглядит так:

String        start    score
TRIRXBGFPI    219      46.1
QBPWJOTFLQ    430      21.5
PWVEEHKTFW    399      37.2
AWGAFAHGQF    246      16.4
ZDLYRUTZBB    380      32.1

Теперь я хочу иметь возможность читать каждую букву строки и записывать позицию каждой буквы "B"вместе с их счетом.Таким образом, ожидаемый результат будет

string         position     start     score
TRIRXBGFPI     6            219       46.1
QBPWJOTFLQ     2            430       21.5
ZDLYRUTZBB     9            380       32.1
ZDLYRUTZBB     10           380       32.1

Мой подход состоял в том, чтобы использовать grepl для столбца строк, чтобы отфильтровать строки без B, а затем запустить два цикла for, чтобы прочитать каждую букву каждой строки и записать ее положение.Может кто-нибудь предложить, пожалуйста, лучший способ сделать это?

Спасибо

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Еще одна опция поворота, использующая gregexpr ......

library(tidyverse)

df %>% 
  mutate(position = gregexpr("B", String)) %>% 
  unnest(position) %>% 
  filter(position>0)

      String start score position
1 TRIRXBGFPI   219  46.1        6
2 QBPWJOTFLQ   430  21.5        2
3 ZDLYRUTZBB   380  32.1        9
4 ZDLYRUTZBB   380  32.1       10
0 голосов
/ 12 декабря 2018

В базе R:

df[["position"]] <- 
   sapply(gregexpr(pattern ='B', df[["String"]]), "[", 1)

subset(df, position > 0)
      String start score position
1 TRIRXBGFPI   219  46.1        6
2 QBPWJOTFLQ   430  21.5        2
5 ZDLYRUTZBB   380  32.1        9

Данные:

df <- data.frame(
  String = c("TRIRXBGFPI", "QBPWJOTFLQ", "PWVEEHKTFW", "AWGAFAHGQF", "ZDLYRUTZBB"), 
  start = c(219L, 430L, 399L, 246L, 380L), 
  score = c(46.1, 21.5, 37.2, 16.4, 32.1)
)
0 голосов
/ 12 декабря 2018

Мы могли бы использовать str_locate

library(tidyverse)
df %>% 
     mutate(position = str_locate_all(String, "B") %>%
                 map(~ .x[,1])) %>% 
     unnest
#      String start score position
#1 TRIRXBGFPI   219  46.1        6
#2 QBPWJOTFLQ   430  21.5        2
#3 ZDLYRUTZBB   380  32.1        9
#4 ZDLYRUTZBB   380  32.1       10

Или использовать gregexpr из base R

lst <- lapply(gregexpr("B", df$String), function(x) as.numeric(x * NA^(x <  0)))
# or use strsplit to split the string and then get the index with which
#lst <- lapply(strsplit(df$String, ""), function(x) {
#       x1 <- which(x == "B")
#       if(length(x1) == 0) NA else x1})
out <- df[rep(seq_len(nrow(df)), lengths(lst)),]
out$position <- unlist(lst)
out1 <- out[!is.na(out$position),]
row.names(out1) <- NULL
out1
#      String start score position
#1 TRIRXBGFPI   219  46.1        6
#2 QBPWJOTFLQ   430  21.5        2
#3 ZDLYRUTZBB   380  32.1        9
#4 ZDLYRUTZBB   380  32.1       10

данные

df <- structure(list(String = c("TRIRXBGFPI", "QBPWJOTFLQ", "PWVEEHKTFW", 
"AWGAFAHGQF", "ZDLYRUTZBB"), start = c(219L, 430L, 399L, 246L, 
380L), score = c(46.1, 21.5, 37.2, 16.4, 32.1)), class = "data.frame", 
row.names = c(NA, -5L))
...