在使用read.csv函数读取数据时,如何跳过R中的最后一列?

5
我曾经看过这篇文章 read.csv and skip last column in R,但没有找到我的答案,于是尝试直接在回答中查找...但这不是正确的方法(感谢 mjuarez 花时间让我重新回到正轨。
原问题如下:

I have read several other posts about how to import csv files with read.csv but skipping specific columns. However, all the examples I have found had very few columns, and so it was easy to do something like:

 columnHeaders <- c("column1", "column2", "column_to_skip")
 columnClasses <- c("numeric", "numeric", "NULL")
 data <- read.csv(fileCSV, header = FALSE, sep = ",", col.names = 
 columnHeaders, colClasses = columnClasses)
所有的回答都很好,但对于我想做的事情并没有用。所以我问了自己和其他人:
在一个函数中,data <- read_csv(fileCSV)[,(ncol(data)-1)] 可以工作吗?
我已经尝试过使用一行 R 代码来获取前6列中的5个,而不是最后一个。为了这样做,我想在列号中使用“-”,你认为这可能吗?我该如何做?
谢谢!

4个回答

4
在基数为r的情况下,需要进行两个步骤操作。例如:
> data <- read.csv("test12.csv")
> data
# 3 columns are returned
          a b c
1 1/02/2015 1 3
2 2/03/2015 2 4

# last column is excluded 
> data[,-ncol(data)]
          a b
1 1/02/2015 1
2 2/03/2015 2

无法在基本的 r 中编写 data <- read.csv("test12.csv")[,-ncol(data)]

但是,如果你知道你的 csv 文件中最大的列数(假设我这里是 3),那么可以这样写:

df <- read.csv("test12.csv")[,-3]
df
          a b
1 1/02/2015 1
2 2/03/2015 2

我已经尝试过了,它可以工作。现在我想进一步操作,给每一列一个类型 df <- read.csv("test12.csv", col_types = "ccd")[,-3]。不确定它是否有效,或者我是否需要在col_types中排除我想要排除的列? - Arthur Camberlein
2
read.csv的参数被称为colClasses。请仔细阅读?read.csv以获取更多信息。请注意,虽然不会有任何影响,但不需要在[, -3]中加入逗号。 - G. Grothendieck

2

赋值语句的右侧先进行处理,因此来自问题的这行代码:

data <- read.csv(fileCSV)[,(ncol(data)-1)]

尝试在定义data之前使用它。另外请注意,上面的内容是要获取倒数第二个字段。要获取除最后一个字段以外的所有字段:

data <- read.csv(fileCSV)
data <- data[-ncol(data)]

如果您知道最后一个字段的名称,比如说它是lastField,那么下面这行代码可以实现这个功能,并且不像上面的代码那样需要读取整个文件再删除最后一个字段,而是只读取除最后一个字段外的其他字段。此外,这只是一行代码。
read.csv(fileCSV, colClasses = c(lastField = "NULL"))

如果你不知道最后一个字段的名称,但是知道有多少个字段,比如说n,那么以下任何一种方法都可以:

read.csv(fileCSV)[-n]

read.csv(fileCSV, colClasses = replace(rep(NA, n), n, "NULL"))

另一种无需先读取最后一个字段的方法是,首先读取标题和第一行以计算字段数(假设所有记录都有相同数量的字段),然后使用该信息重新读取文件。

n <- ncol(read.csv(fileCSV, nrows = 1))

利用前面两个涉及 n 的语句之一。

感谢@Grothendieck的评论,我会利用这些知识继续前进! - Arthur Camberlein

1

由于在调用时data变量尚未初始化,因此无法在一行中完成。因此,命令ncol(data)将触发错误。

您需要使用两行代码,首先将数据加载到data变量中,然后通过使用data[,-ncol(data)]data[,1:(ncol(data)-1)]来删除最后一列。


感谢@toroberger的建议和额外提供的信息。 - Arthur Camberlein

1

不是单个函数,但至少是使用 dplyr 的单行代码(免责声明:我从未使用过 dplyrmagrittr,因此可能存在更优化的解决方案使用这些库)

library(dplyr)
dat = read.table(fileCSV) %>% select(., which(names(.) != names(.)[ncol(.)]))

谢谢,从没想过使用magrittr或dplyr来做这件事! - Arthur Camberlein
@ArthurCamberlein 不用谢。虽然你已经接受了一个答案(通常建议等待一段时间,但完全由你决定哪个答案对你最有帮助),但我看到你没有给其他有用的答案点赞(尽管你感谢了它们各自的作者)。所以考虑给任何有帮助的答案点赞,现在你有必要的声望来做到这一点 :) - catastrophic-failure

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接