Как динамически добавлять данные в фрейм данных?

У меня есть данные, которые нужно очистить для каждой строки в файле, и я хочу вставить очищенные данные в базу данных SQLite3. Я использую библиотеку RSQLite, для которой требуется датафрейм. Вот код, который я пытаюсь заставить работать:

# Select feature names for use as column names in X train/test loading
feature_names <- unlist(dbGetQuery(con, "select feature_name from features order by feature_id"), use.names = FALSE);

# Load X training data
X_train_lines <- readLines("data/train/X_train.txt"); # Space delimited with leading and trailing spaces
X_train_values <- vector("list", length(X_train_lines));
names(X_train_values) <- feature_names; # colnames or names?
for (index in 1:length(X_train_lines)) {
  cleaned_line <- gsub("^ *|(?<= ) | *$", "", X_train_lines[index], perl=TRUE); # remove extraneous whitespaces
  X_train_values[index] <- strsplit(cleaned_line, " "); # Wondering if X_train_values[index] is correct? 
}
# Write features data to features table
dbWriteTable(con, "X_train", as.data.frame(X_train_values), row.names = FALSE);

Хотя код выполняется без инцидентов, когда я пытаюсь просмотреть базу данных с помощью DbVisualizer, я получаю сообщение об ошибке:

Произошла ошибка при выполнении операции:
неверно сформированная схема базы данных (X_train) - слишком много столбцов в X_train

Мое единственное предположение, что строки и столбцы каким-то образом транспонированы. Мои имена столбцов должны быть значением feature_names вектор.

Кроме того, если у кого-то есть предложения для лучшего подхода...

ОБНОВИТЬ

Я пытался сделать dput, хотя понятия не имел, на что смотрю. Вот вершина резюме:

head(summary(X_train_values))

                   Length Class    Mode       
tBodyAcc-mean()-X "561"  "-none-" "character"
tBodyAcc-mean()-Y "561"  "-none-" "character"
tBodyAcc-mean()-Z "561"  "-none-" "character"
tBodyAcc-std()-X  "561"  "-none-" "character"
tBodyAcc-std()-Y  "561"  "-none-" "character"
tBodyAcc-std()-Z  "561"  "-none-" "character"

Опять же, это заставляет меня поверить, что все данные перепутаны. Он должен иметь 561 столбец, некоторые из которых представлены выше как tBodyAcc-mean()-X и т. Д. Значения столбцов должны быть числами с плавающей точкой, которых я не вижу выше.

Команда таблицы не работает:

table(X_train_values)
Error in table(X_train_values) : 
  attempt to make a table with >= 2^31 elements

У меня должно быть 7352 строки с 561 столбцом.

ОБНОВЛЕНИЕ 2

Я считаю, что моя проблема в том, что я пытаюсь использовать список, например, массив или массивы. В Ruby, например, я мог бы сделать что-то вроде этого:

x_train_values = []
x_train_lines.each { |line| x_train_values << line.split(' ') }

1 ответ

В следующих строках

for (index in 1:length(X_train_lines)) {
    cleaned_line <- gsub("^ *|(?<= ) | *$", "", X_train_lines[index], perl=TRUE);
    X_train_values[index] <- strsplit(cleaned_line, " ");
}

вы используете одинарные квадратные скобки ([) для доступа к столбцам фрейма данных, когда вы должны использовать двойные ([[). Когда вы используете X_train_lines[index]возвращается фрейм данных, который имеет один столбец, равный X_train_lines[index], Когда вы используете X_train_lines[[index]]однако, фактическое содержимое этого столбца возвращается (см. http://adv-r.had.co.nz/Subsetting.html для более подробной информации).

Теперь путь gsub работает, это то, что он сначала преобразует свой аргумент в символ, используя as.character и затем обрабатывает это. В твоем случае, X_train_lines[index] возвращает data.frame, чей единственный столбец является фактором (я полагаю), и поэтому при приведении к символу вы получите уровни фактора, а не фактическое содержимое! Итак, вы на самом деле звоните gsub на строку, которая выглядит как "1:2:3:...". Если вместо этого вы используете двойные скобки, то gsub будет приводить фактор (вместо фрейма данных) к персонажу, который будет работать по желанию.

Кроме того, в R вам не нужно заканчивать свои строки ;, Это необходимо только для разделения нескольких операторов в одной строке.

Наконец, лучше всего избегать for циклы, потому что они могут быть медленными и потому что есть более эффективные функции с более простым синтаксисом, которые обычно могут выполнить то, что вам нужно (например, lapply, apply, sweep, так далее). Для столбцов / строк / поэлементных операций над фреймом данных / матрицей / и т. Д. Вы можете использовать apply, в этом случае ваш код будет выглядеть

apply(X_train_values, 2, gsub, pattern = "^ *|(?<= ) | *$",
    replacement = "", perl = T)
Другие вопросы по тегам