【问题标题】:Import exponential values as numeric in R在 R 中将指数值作为数字导入
【发布时间】:2013-06-24 11:20:37
【问题描述】:

我必须自动导入许多数据集,第一列是名称,因此是字符向量,第二列是数字向量,因此我将这些规范与 read.table 一起使用: colClasses = c("character" , "数字")。

如果我有一个像这样保存在 df_file 中的数据框,这将非常有用:

df<- data.frame(V1=c("s1","s2","s3","s4"), V2=c("1e-04","1e-04","1e-04","1e-04")

read.table(df_file, header = FALSE,  comment.char="", colClasses = c("character", "numeric"), stringsAsFactors=FALSE)

问题是在某些情况下,我在第二列中有具有指数形式的数值的数据框,在这些情况下,导入不起作用,因为它无法将该列识别为数字(或者它导入为“字符" 如果我​​没有指定 colClasses),那么我的问题是: 即使值是指数的,如何指定要作为数字导入的列?

例如:

df<- data.frame(V1=c("s1","s2","s3","s4"), V2=c("10^(-4)","10^(-4)","10^(-4)","10^(-4)"))

我希望将所有指数值作为数字导入,但即使在导入后我尝试从字符更改为数字时,我也会得到所有“NA”(as.numeric(as.character(df$V2)) "警告信息:强制引入的 NA")

我也尝试将“真实”或“复杂”与 colClasses 一起使用,但它仍将指数作为字符导入。

请帮忙, 谢谢!

【问题讨论】:

  • 尝试类似:as.numeric(gsub("0\\^", "e", gsub("[()]", "", df$V2)))
  • 嗨,阿伦,谢谢。所以我想没有“简单的出路”吗?意思是,如果我想这样做,我是否必须先导入第二列“as.character”的所有数据集,然后仅在列具有指数项时才这样做?
  • @user2337032,您可以改用readLines。我已经发布了答案。
  • 谢谢你,Arun 你的功能也能正常工作!

标签: r import


【解决方案1】:

我认为问题在于你的指数形式与 R 风格不匹配。如果您将它们作为字符向量读入,如果您知道它们都是指数,则可以将它们转换为指数。使用 gsub 去除“10^(”和“)”,留下“-4”,转换为数字,然后转换回指数。可能不是最快的方法,但它有效。

从你的例子:

 df<- data.frame(V1=c("s1","s2","s3","s4"), V2=c("10^(-4)","10^(-4)","10^(-4)","10^(-4)"))
 df$V2 <- 10^(as.numeric(gsub("10\\^\\(|\\)", "", df$V2)))
 df
#  V1    V2
#1 s1 1e-04
#2 s2 1e-04
#3 s3 1e-04
#4 s4 1e-04

详细情况:gsub("10\\^\\(|\\)", "", df$V2) 将 10^( 和 ) 替换为空字符串(您需要转义克拉和括号),as.numeric() 将您的 -4 字符串转换为数字 -4,然后您只是在刚刚创建的数字向量的每个元素上运行 10^。

【讨论】:

  • 谢谢,这行得通。我只是首先作为字符导入并用grep检查是否有“^”,然后使用你的代码。谢谢!
【解决方案2】:

如果您在data.framestringsAsFactors=FALSE 中阅读,则相关列应以字符向量的形式出现,在这种情况下您可以简单地执行以下操作:

transform(df, V2=eval(parse(text=V2)))

【讨论】:

  • 这要简单得多!只有一个问题,如果我有 colnames(所以 header=TRUE)并想替换第二列,我将如何使用它?这给了我一个错误:df[,2]
  • 警告信息:在[&lt;-.data.frame(*tmp*, , 2, value = list(V1 = c("s1", : 提供2个变量替换1个变量
  • 你能把dput(head(df, 5))的输出贴出来吗?
  • 是的,> dput(head(df, 5)) structure(list(V1 = structure(1:4, .Label = c("s1", "s2", "s3", "s4"), class= "因子"), V2 = 结构(c(1L, 1L, 1L, 1L), .Label = "10^(-4)", class= "因子")), .Names = c("V1", "V2"), row.names = c(NA, 4L), class= "data.frame")
  • 您的 V2 列是一个因素。您要么必须转换为字符,要么使用as.is=TRUE 再次读取它。您收到错误的原因是因为您想要df &lt;- transform(df, V2=eval(parse(text=as.character(V2)))),而不是df[, 2] &lt;- ...
【解决方案3】:

您可以使用readLines 首先加载数据并执行所有需要的操作,然后使用read.tabletextConnection,如下所示:

tt <- readLines("~/tmp.txt")
tt <- gsub("10\\^\\((.*)\\)$", "1e\\1", tt)
read.table(textConnection(tt), sep="\t", header=TRUE, stringsAsFactors=FALSE)
  V1    V2
1 s1 1e-04
2 s2 1e-04
3 s3 1e-04
4 s4 1e-04

【讨论】:

  • 这实际上可能比先读取所有文件要快,而且对我来说更好,因为我的文件很大!谢谢!
  • 不过,我认为作为具有单独列的数据框重新导入存在问题: tt
  • 那是因为您使用的是\( 而不是\\(\) 而不是\\)。你应该逃跑两次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多