R: strsplit в каждом столбце; Ошибка: элемент замены 1 имеет [y] строк для замены 1 строки

Я работаю с фреймом данных (я назову его «буквами») в R, где 15 строк по 2 столбца. Каждый столбец 2 содержит строку символов типа «A | B | C | D | E». Я хочу разбить строку в каждом месте a | похоже, получает вектор c («A», «B», «C», «D», «E»). Вот моя лучшая идея, как это сделать:

for(i in 1:nrow(letters)){
  letters[i,2] <- strsplit(letters[i,2], split = "[|]")
}

Я получаю аналогичную ошибку, описанную в здесь («замена имеет [x] строк, данные имеют [y]»), и, похоже, пытается создать отдельный столбец для каждого индекса выходного вектора. Я уверен, что это простой вопрос, но я новичок в R и застрял.

Попробуйте запустить только strsplit(letters[i,2], split = "[|]") и проверьте вывод для отладки

Tung 30.05.2018 20:05

@Tung > strsplit(letters[i,2], split = "[|]") возвращает [[1]] [1] "A" "B" "C" "D" "E"

gooseshoes 30.05.2018 20:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
475
2

Ответы 2

strsplit(letters[i,2], split = "[|]")[[1]] то, что вы ищете? Вы не сможете вернуть этот вектор в letters[i,2], поскольку он имеет длину 5 (вместо 1).

Да, это то, что я ищу. Я не понимал, что вы не можете хранить вектор в ячейке фрейма данных.

gooseshoes 30.05.2018 21:28

Что бы вы посоветовали сделать, если в конце концов я попытаюсь спросить: в каких строках стоит буква «А»? Какие содержат "D"? и поэтому мне нужен список, связанный с каждым именем строки?

gooseshoes 30.05.2018 22:01

Используйте grepl("A", letters[[2]]), чтобы определить, содержит ли каждое значение "A".

Nathan Werth 30.05.2018 22:51

Ваш второй столбец (я думаю) - это вектор символов. strsplit, как упоминается в документации (?strsplit), возвращает список. Прежде чем мы перейдем к Зачем, произошла ваша конкретная ситуация, несколько общих советов:

  1. Создайте новый столбец вместо того, чтобы заменять существующий. Это дает дополнительное преимущество в том, что не теряет исходных значений.
  2. Заменяйте значения в столбце только новыми значениями того же класса (например, символ вместо символа, целое число для целого).

Поэтому я предлагаю добавить новый столбец разделенных значений:

letters[["splits"]] <- strsplit(letters[[2]], split = "|", fixed = TRUE)

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

Почему возникла твоя проблема

Давайте разберем оператор присваивания:

letters[i,2] <- strsplit(letters[i,2], split = "[|]")

Слева от <- находится letters[i, 2], который является data.frame. data.frame хранит все свои данные в списке. R позволяет нам использовать этот факт, особенно при назначении. Мы можем добавлять или заменять столбцы так же, как добавляя или заменяя элементы в списке.

# This...
letters[, "one"] <- 1
letters[, "two"] <- 2
# is effectively the same as this
letters[, c("one", "two")] <- list(1, 2)

Справа от -> у нас есть вызов strsplit(), который возвращает list. Как и в примере выше, если вы назначите список подмножеству data.frame, он будет преобразован в сам data.frame. Каждый элемент списка будет считаться столбцом. Итак, задание разыгрывается так:

  1. Если letters[i,2] - это "A|B|C|D|E", то strsplit(letters[i,2], split = "[|]") - это list(c("A", "B", "C", "D", "E")).
  2. Назначение проверяет обе стороны и рассматривает data.frame как «более высокий» тип, поэтому он приводит список к data.frame. Правая сторона теперь фактически data.frame(c("A", "B", "C", "D", "E")).
  3. Теперь он пытается назначить data.frame с 1 столбцом и 5 рядов подмножеству с 1 столбцом и 1 ряд. Эти размеры не совпадают, поэтому он берет все, что может, с правой стороны (только первую строку) и предупреждает вас о том, что произошло.

Почему предложенное задание работает

Так почему же в этом нет никакого принуждения?

letters[["splits"]] <- strsplit(letters[[2]], split = "|", fixed = TRUE)

В левой части используется подмножество [[ (обработка data.frame как списка) для добавления или замены столбца "splits". Так что никакого принуждения не бывает.

Кроме того, data.frame может иметь list в качестве столбца, точно так же, как list может иметь list в качестве элемента. Колонка data.frame должна удовлетворять двум вещам:

  1. Это должен быть вектор.
  2. Его длина должна быть равна количеству строк в data.frame (при необходимости, попытка повторного использования).

list - это тип вектора. strsplit() возвращает список той же длины, что и его входные данные, поэтому оба критерия соблюдаются.

Другие вопросы по теме