如何动态地将数据添加到数据框?

时间:2014-07-03 00:23:26

标签: r sqlite dataframe rsqlite

我需要为文件中的每一行清理数据,并且我想在SQLite3数据库中插入已清理的数据。我使用的RSQLite库需要dataframe。这是我尝试工作的代码:

# 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查看数据库时,我收到错误:

An error occurred while performing the operation:
malformed database schema (X_train) - too many columns on X_train

我唯一的猜测是行和列以某种方式转换。我的列名应该是feature_names向量的值。

另外,如果有人对更好的方法有任何建议......

更新

我尝试过输入,虽然我不知道我在看什么。这是摘要的顶部:

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命令不起作用:

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

我应该有7,352行,561列。

更新2

我相信我的问题是我尝试使用像数组或数组这样的列表。例如,在Ruby中,我可以这样做:

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

1 个答案:

答案 0 :(得分:0)

以下几行

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,其单列是一个因素(我猜),因此当强制转换为一个字符时,你将获得因子级别,而不是实际内容!所以你实际上是在一个看起来像&#34; 1:2:3:...&#34;的字符串上调用gsub。如果你使用双括号,那么gsub会强制一个因子(而不是数据框)到一个字符,这将按照需要工作。

另外,在R中,您不需要使用;结束行。这只需要在同一行上分隔多个语句。

最后,最好尝试避免for循环,因为它们可能很慢,因为有更高效的函数,语法更简单,通常可以满足您的需要(如lapply,{{ 1}},apply等)。对于数据框/矩阵/等上的列/行/元素操作,您可以使用sweep,在这种情况下,您的代码将类似于

apply