2014-10-15 5 views
1

Я хочу найти разные позиции текста внутри подстроки. Скажем, у меня есть кадр данных, как показано ниже:Разделите значения столбцов от c (a, b) до a и b в кадре данных R

Key String 
10 09123022130908123 
11
12 12387109387126309 

Не знаю, как сделать это в виде таблицы здесь, но идея каждый ключ имеет длинную строку цифр. Чтобы найти расположение текста «09» в каждой строке, я использовал код:

df$try<-gregexpr(pattern ='09',df$string) 

Это дало мне таблицу

Key String   try 
10 09123022130908123 c(1,11) 
11c(11,15) 
12 12387109387126309 c(7,16) 

Теперь я хочу, чистые номера в разных столбцах, а не один столбец, содержащий c (a, b). Как можно разделить такие значения на a и b под разными столбцами? Любые другие предложения по получению всех позиций требуемого текста в подстроке приветствуются. Thanks

+0

Вы, вероятно, хотите, чтобы функция 'unlist' была завершена в какой-либо оператор' apply'. – n8sty

ответ

1

Возможно, не супер красивый, но рабочий. Сначала ваши данные:

df <- data.frame(
    key = c(10,11,12,13), 
    string = c( 
    "09123022130908123", 
    "", 
    "12387109387126309", 
    "88888888888888809" 
) 
) 

Я использую здесь lapply и function, whichmatch дает первый, второй и т.д. матч

searchString <- function(string, whichmatch) { 
    x <- unlist(gregexpr(pattern ='09', string))[whichmatch] 
    return(x) 
} 
df$a <- lapply(df$string, FUN = function(x) { searchString(x, 1) }) 
df$b <- lapply(df$string, FUN = function(x) { searchString(x, 2) }) 
rm(searchString) 

    key   string a b 
1 10 09123022130908123 1 11 
2 11
3 12 12387109387126309 7 16 
4 13 88888888888888809 16 NA 
+0

Эй, спасибо за ответ. Но это работает не так, как ожидалось. Он бросает столбец с одинаковыми значениями, что соответствует значению [whichmatch] из всего столбца «string». Я думаю, что это из-за случаев, когда у меня есть одноразрядные числа, т. Е. Вместо двух находок шаблон присутствует только один раз, а gregexpr() дает правильное число. –

+0

Можете ли вы разместить какой-нибудь код? Или глава ваших данных? Причина, по которой функция должна возвращать NA, если у вас есть только одно совпадение (я собираюсь изменить пример здесь). –

+0

Perfect. Спасибо тонну Ричарда и z-cool! В результате я использовал функцию z-cool. –

2

Вы все еще можете использовать gregexpr. Но вам нужно будет перебирать результаты gregexpr и делать совпадения одинаковой длины, заполняя пустые значения NA. С df (публикуемыми ниже), вы могли бы сделать

g <- gregexpr("09", df$string, fixed = TRUE) 
cbind(df, t(sapply(g, `length<-`, max(sapply(g, length))))) 
# key   string 1 2 
# 1 10 09123022130908123 1 11 
# 2 11
# 3 12 12387109387126309 7 16 
# 4 13 88888888888888809 16 NA 

В случае, если вы делаете это на несколько моделей, вот небольшая функция, которая может помочь

where <- function(data, col, pattern, ...) 
{ 
    g <- gregexpr(pattern, data[[col]], ...) 
    dc <- do.call(rbind, lapply(g, function(x) { 
     x <- if(any(x < 0)) NA else x 
     `length<-`(x, max(sapply(g, length))) 
    })) 
    colnames(dc) <- letters[1:ncol(dc)] 
    cbind(df, dc) 
} 

И несколько спусков образца:

where(df, "string", "8", fixed = TRUE) 
# key   string a b c d e f g h i j k l m n o 
# 1 10 09123022130908123 14 NA NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 2 11NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 3 12 12387109387126309 4 10 NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 4 13 88888888888888809 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
where(df, "string", "09", fixed = TRUE) 
# key   string a b 
# 1 10 09123022130908123 1 11 
# 2 11
# 3 12 12387109387126309 7 16 
# 4 13 88888888888888809 16 NA 
where(df, "string", "12", fixed = TRUE) 
# key   string a b 
# 1 10 09123022130908123 3 15 
# 2 11
# 3 12 12387109387126309 1 12 
# 4 13 88888888888888809 NA NA 

данных:

df <- 
structure(list(key = c(10, 11, 12, 13), string = structure(c(2L, 
1L, 3L, 4L), .Label = c("", "09123022130908123", 
"12387109387126309", "88888888888888809"), class = "factor")), .Names = c("key", 
"string"), row.names = c(NA, -4L), class = "data.frame") 
Смежные вопросы