我对R很新,但似乎这是一个我无法找到答案的具体问题。
我的程序读入一些数据,然后根据我传递的列号向量将该数据的某些列重新绑定到几个数据帧之一,如下所示:
filename <- c("vector", "full", "of", "filenames")
colVal <- (32)
InMat <- data.frame()
for (i in 1:length(filename)){
file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)])
#...other matricies...
}
我的问题在于只有一个所需列的情况,即colVal需要一个值。在这种情况下,我发现InMat基本上是从我需要的转换。更糟糕的是,当我读取多个文件时,它会转换所需的转置列,因此我得到的行数等于我正在读取的文件数,其列数与每个文件的每个所需列中的行数相同。
似乎如果有2个所需的列(即colVal需要两个或更多个值),那么它就像我期望的那样(即,一个列被读取并作为一列存储在InMat中,每个附加文件的列都存储在下面)。
我的问题是为什么当只有一个所需的列值传递给它时rbind的行为方式不同,并且如果有一个简单的方法(读取;不添加一些笨重的if或for循环来检查)以避免这种情况?
谢谢!
答案 0 :(得分:0)
当您只拍摄一列时,它就变成了一个矢量。如果您只是将所有值附加到向量而不是矩阵
中会更好InVec <- c()
for (i in 1:length(filename)){
file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
InVec <- c(InVec, file[-1, colVal)])
#...other matricies...
}
使用c()将比rbind快得多
答案 1 :(得分:0)
简短回答:[.data.frame
(数据框上的[
运算符)默认情况下将输出转换为可能的最低维度(通过参数drop=TRUE
)。如果你只拉一列,那么它会转换为一个向量,然后通过rbind
创建一个带有其他向量的矩阵到矩阵中。当您提取两个或更多列时,您将获得一个数据框,因此rbind
的输出是一个数据框。
快速解决方法是更改此行:
InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)]) #old line
InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal),drop=FALSE]) #new line
更像R的编码方式是使用lapply
并调用rbind
一次。因为R是逐个复制的,所以通过重复连接/添加来增长对象的效率非常低(参见R Inferno的第二个圆圈)。
filename <- c("vector", "full", "of", "filenames")
colVal <- (32)
dfm <- lapply(filename, read.table
, header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
dfm <- lapply(dfm,`[`,colVal)
dfm <- do.call(rbind,dfm)
如果您知道要预先提取的列的位置,可以使用colClasses
的{{1}}参数并跳过阅读整个表:
read.table