Вложенный цикл For в R с ошибкой «числовое выражение содержит 2 элемента: используется только первый»

#r #for-loop #nested-for-loop

#r #for-цикл #вложенный цикл for #цикл for

Вопрос:

Я пытаюсь напечатать комбинации из 3 последовательных символов в строке, используя вложенные циклы for в R. Код печатает комбинации, однако я получаю сообщение об ошибке только для одного из элементов, а не для каждой строки в фрейме данных.

 x <- data.frame(Pattern = c("abcdef", "hijklmnop"), id = 1:2)

output <- vector("character", length(x$Pattern))

for (i in 1:nrow(x)) {  

  file <- x$Pattern[i]

  for (j in 1:(str_length(x$Pattern))) {
    output[j] <- substr(file, j, j 2)
  }

}

numerical expression has 2 elements: only the first usednumerical expression has 2 elements: only the first used
> 
> output
[1] "hij" "ijk" "jkl" "klm" "lmn" "mno"

  

Здесь происходит 2 вещи, которые не работают. Во-первых, output инициированный var использует длину первого шаблона (длина = 6) и печатает комбинации на основе этой длины, однако я ищу результат, который является длиной строки (длина = 9). Предполагаемый результат приведен ниже без использования вложенного цикла for .

   for (j in 1:9) {
    
    output[j] <- substr(file, j, j 2)
    
  }

output
[1] "hij" "ijk" "jkl" "klm" "lmn" "mno" "nop" "op"  "p"  

  

Я урезаю его дальше, чтобы у меня был только список комбинаций для 3 последовательных символов в строке.

 list(output[1:(length(output)-3)])
[[1]]
[1] "hij" "ijk" "jkl" "klm" "lmn" "mno"
  

Вторая проблема, с которой я сталкиваюсь, заключается в том, что на выходе выводятся только комбинации для второй символьной строки в моем списке. Я пытался изменить 1:nrow(a) на seq_along и length(a) , как рекомендовано в других сообщениях, но это не работает. Предполагаемый результат приведен ниже.

 a$combo <- output

a$combo
[1] c("abc","bcd","cde","def") c("hij","ijk","jkl","klm","lmn","mno")

  

Комментарии:

1. Является ли c («hij», «ijk», «jkl», «klm», «lmn», «mno») не предполагаемым результатом? Если нет, то как должен выглядеть результат?

2. vector использует «double» как синоним «числового». Вы помещаете символьные строки в двойной вектор, вместо этого вы должны инициализировать output as vector("character", ...) . (Но на самом деле кажется, что это может быть a list() ?)

3. Да, хорошая точка @flo! Предполагаемый результат — это комбинации обеих строк. В идеале я хотел бы добавить его в качестве дополнительного столбца в dataframe a , так что что-то вроде a$combo <- output where output [1] «abc» «bcd» «cde» «def» [2] «hij» «ijk» «jkl» «klm» «lmn» «mno»

4. Спасибо @GregorThomas. После изменения vector списка «Кому» я получаю результат, подобный приведенному ниже, что не входит в мои намерения. Я все еще получаю ошибку после изменения с vector("double",... на vector("character",... , однако имеет смысл сделать это редактирование в любом случае. [[1]] [1] «hij» [[2]] [1] «ijk» [[3]] [1] «jkl» [[4]] [1] «klm» [[5]] [1] «lmn» [[6]] [1] «mno»

Ответ №1:

 x <- data.frame(Pattern = c("abcdef", "hijklmnop"), id = 1:2)

# number of additional letters in individual character string
add_letters = 2

library(stringr)

output = list()


for (i in 1:nrow(x)) {  
    
    file <- x$Pattern[i]
    
    l = list()
    
    for (j in 1:(str_length(x$Pattern[i])-add_letters)) {
        
        l[j] <- c(substr(file, j, j add_letters))
    
    }
    
    output[[i]] = l 
    
}

x$combo = output
  

Решение со списками — как предложил Грегор Томас.