将CSV数据集导入R后,值变成了因子

76

我对R非常陌生,无法访问我导入的数据集。 我正在使用RStudio,并在导入csv文件时使用了“导入数据集”功能,然后将控制台窗口中的行粘贴到源窗口中。 代码如下:

setwd("c:/kalle/R")
stuckey <- read.csv("C:/kalle/R/stuckey.csv")
point <- stuckey$PTS
time <- stuckey$MP

然而,数据不是我习惯的整数或数字,而是因子,因此当我尝试绘制变量时,只会得到直方图,而不是通常的图。在检查数据时,它似乎是有序的,只是因为它是以因子形式出现,所以我无法使用它。


1
正如Hong Ooi所提到的,你可能在不应该有的地方有非数字值。尝试查看数据(例如使用View(stuckey))以查看问题出在哪里。 - Richie Cotton
嗨,我有一个大文件,大小为54000 * 200维度数据,以csv格式编写。我已经在Java文件中读取了数据,并在转换为Double时没有遇到任何异常。但是,在R中读取时,我遇到了同样的问题。我尝试了这里发布的方法,但是没有成功。附言:我是R的新手。 - Rudra Murthy
8个回答

76

数据导入函数(这里是: read.csv())和全局选项都可以提供stringsAsFactors=FALSE,这应该可以解决此问题。


20
我认为 stringsAsFactors 在这种情况下并不能帮助,它只控制将字符转换为因子的过程。它不会影响 read.csv 导入列的数值型或字符型状态,而这才是潜在的问题所在。 - Hong Ooi
7
此外,stringAsFactor = FALSE 通常会强制将格式转换为字符类型,这恰恰与此处需要实现的相反。 - gented
我不推荐这个解决方案,因为它只是将其转换为字符,完全没有意义。 - ABCD
最好通过 options('stringsAsFactors'=FALSE) 在全局范围内设置合理的默认值,这样你就不会忘记。 - smci
3
你和我都不知道这个问题没有数据集是真实可验证的,所以如果你基于这个原因给它投了反对票,那么你做错了。无论如何,我不明白为什么人们会对一个八年前的答案如此激动。我们已经无数次讨论过数据的读取,有时甚至使用 mcve 进行讨论。如果没有数据集,我们所做的一切都只是猜测。 - Dirk Eddelbuettel
显示剩余4条评论

29

默认情况下,read.csv会检查数据的前几行,以确定是否将每个变量视为数值型。如果它发现非数值型的值,就会将该变量视为字符数据,并将字符变量转换为因子。

看起来你的数据集中PTS和MP变量包含非数值型数据,这就是你得到意外结果的原因。你可以使用以下代码将这些变量强制转换为数值型:

point <- as.numeric(as.character(point))
time <- as.numeric(as.character(time))

但是任何无法转换的值都将变为缺失值。(R FAQ提供了一种略有不同的因子到数值的转换方法,但我经常记不住它是什么。)

但是任何无法转换的值都将变为缺失值。(R FAQ提供了一种略有不同的因子到数值的转换方法,但我经常记不住它是什么。)


请参见此处的factor2numeric: http://4dpiecharts.com/2011/01/10/really-useful-bits-of-code-that-are-missing-from-r/ - Richie Cotton
是的。这应该被接受。另一个答案没有进行任何适当的转换。 - ABCD

23

你可以通过设置 options(stringsAsFactors=F) 来全局为所有的read.csv/read.* 命令设置不将字符串作为因子(即不将字符串转换为分类变量)。

然后按如下方式读取文件: my.tab <- read.table( "filename.csv", as.is=T )


8
注意大小写:应该使用'stringsAsFactors'而不是'StringsAsFactors'。 - artdv
1
或者您可以简单地向函数添加选项:my.tab <- read.table("filename.csv", stringsAsFactors=F) - user890739
我喜欢options方法,因为它可以与其他读取方法(如read_rds)一起使用。 - done_merson
我会删除所有关于 read.delim() 的提及,因为它只是 read.csv(... sep = "\t") 的一个薄包装器。否则,这个答案是这个问题中最好的答案。而且 OP 特别使用了 read.csv()(它也只是 read.table(... sep=',') 的一个薄包装器)。 - smci

8

导入csv数据文件时,导入命令应反映每个列之间的数据分隔符(;)和数值变量的浮点数分隔符(例如,对于数字变量=2.5,这将是“,”)。

因此,导入csv的命令必须更加全面,具有更多的命令:

    stuckey <- read.csv2("C:/kalle/R/stuckey.csv", header=TRUE, sep=";", dec=",")

这应该导入所有变量为整数或数字。

4

这些答案都没有提到colClasses参数,这是在read.csv中指定变量类别的另一种方法。

 stuckey <- read.csv("C:/kalle/R/stuckey.csv", colClasses = "numeric") # all variables to numeric

或者您可以指定要转换的列:

stuckey <- read.csv("C:/kalle/R/stuckey.csv", colClasses = c("PTS" = "numeric", "MP" = "numeric") # specific columns to numeric

注意,如果一个变量无法转换为数字,则默认将其转换为因子(factor),这使得它更难以转换为数字。因此,建议仅将所有变量读入为'character'colClasses = "character",然后在读入csv之后将具体列转换为数字:

stuckey <- read.csv("C:/kalle/R/stuckey.csv", colClasses = "character")
point <- as.numeric(stuckey$PTS)
time <- as.numeric(stuckey$MP)

2

我也是R的新手,之前遇到了同样的问题。但是后来我查看了数据,发现这是由于我的csv文件在所有数字列中使用逗号分隔符(例如:1,233,444.56而非1233444.56)导致的。

我在csv文件中去掉了逗号分隔符,然后重新载入到R中。现在我的数据框将所有列都识别为数字。

我相信有一种方法可以在read.csv函数内部处理这个问题。


1
read.csv命令中包含strip.white = TRUE时,这对我起作用。
(我在这里找到了解决方案。)

0
对我来说,解决方案是包括 skip = 0(在文件顶部跳过的行数。可以设置> 0)
mydata <- read.csv(file = "file.csv", header = TRUE, sep = ",", skip = 22)

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