【问题标题】:Using read.csv.sql to select multiple values from a single column使用 read.csv.sql 从单个列中选择多个值
【发布时间】:2015-01-07 19:52:38
【问题描述】:

我正在使用 sqldf 包中的 read.csv.sql 尝试读取行的子集,其中子集从多个值中选择 - 这些值存储在另一个向量中。

我已经破解了一种有效的表单方法,但我想看看传递sql 语句的正确方法。

下面的代码给出了最小的例子。

library(sqldf)

# some data
write.csv(mtcars, "mtcars.csv", quote = FALSE, row.names = FALSE)

# values to select from variable 'carb'
cc <- c(1, 2)

# This only selects last value from 'cc' vector
read.csv.sql("mtcars.csv", sql = paste("select * from file where carb = ", cc ))

# So try using the 'in' operator - this works
read.csv.sql("mtcars.csv", sql = "select * from file where carb in (1,2)" ) 

# but this doesn't
read.csv.sql("mtcars.csv", sql = paste("select * from file where carb in ", cc ))

# Finally this works
read.csv.sql("mtcars.csv", sql = paste("select * from file where carb in ", 
                                       paste("(", paste(cc, collapse=",") ,")")))

上面的最后一行有效,但是有没有更简洁的方法来传递这个语句,谢谢。

【问题讨论】:

  • 想不出更干净的方法。当我遇到这个问题时,我通常会这样做。

标签: r sqldf


【解决方案1】:

1) fn$ 替换可以用 gsubfn 的fn$ 完成(由 sqldf 自动拉入)。请参阅 sqldf home page 上的 fn$ 示例。在这种情况下,我们有:

fn$read.csv.sql("mtcars.csv", 
  sql = "select * from file where carb in ( `toString(cc)` )")

2) join 另一种方法是创建一个包含所需 carb 值的 data.frame 并与之执行连接:

Carbs <- data.frame(carb = cc)
read.csv.sql("mtcars.csv", sql = "select * from Carbs join file using (carb)")

【讨论】:

  • 太好了,谢谢 Gabor;我浏览了您的主页,但没有开始使用 fn$ 方法 - 我会花一些时间来尝试理解它。你的第二种方法更像是我所期待的 sql 魔法。这是否仍然导致 R 仅读取选定的行(我正在处理一个非常大的数据集)?
  • 是的,mtcars.csv 和 Carbs 被读入 sqlite,连接在那里完成,只有结果被读回 R。
【解决方案2】:

您可以使用deparse,但我不确定它是否比您已有的干净得多:

read.csv.sql("mtcars.csv",
             sql = paste("select * from file where carb in ", gsub("c","",deparse(cc)) ))

请注意,这并不是一个真正的通用解决方案,因为deparse 不会总是为您提供正确的字符串。它恰好在这种情况下起作用。

【讨论】:

  • 感谢您的回答托马斯。虽然沿用相同的路线,但它有点清洁。您的最后一句话表明paste 方法更安全? (尽管期待另一种替代方法/比粘贴更好的方法)
  • @user2957945 是的,这不会一概而论,因为deparse 以不同的方式表示不同的向量。恰好对于向量 1:2,它以您需要的方式表示它。
  • 我永远不会使用deparse。例如看deparse(1:2)deparse(c(1,2)) 之间的区别,即使论点基本相同。此外,deparse 可以返回长于一个的字符向量(例如 deparse(c(1:100,101,102:200)))。
  • @nicola;感谢您的解释 - 它显示了我认为 Thomas 暗示的一些问题,但由于我不熟悉 deparse,我很欣赏这个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 2018-05-15
  • 2011-08-30
  • 2021-11-10
  • 2022-06-23
相关资源
最近更新 更多