【问题标题】:Assigning names to a dataframe via a loop in R通过R中的循环为数据框分配名称
【发布时间】:2011-11-22 07:56:48
【问题描述】:

似乎有一些类似的问题,但在这么晚的时候我无法完全理解它们

我正在尝试基于 sql 调用来操作一组数据帧 - 类似这样的

x <- c(3,9,12) # x is of variable length in real world

for (i in 1:length(x)) {
nam <- paste("df",i, sep="")
assign(nam) <- sqlQuery(channel,paste(
"Select myCol from myTable where myVal =",x[i],sep=""));
}

所以我在寻找数据帧 df1、df2、df3,然后我可以将它们组合起来等等。

Andrie 在下面的回答很完美,但我无法将其扩展到两个变量

myQuery <- function(t,x){
  sqlQuery(channel,paste("Select myCol from myTable where myTextVal='",t,"' and myVal =", x, sep=""))
}

x <- c(3,9,12) 
t <-c("00","10","12")
myData <- lapply(c(t,x), myQuery)

我收到“粘贴错误...参数“x”丢失,没有默认值”

我不确定是不是因为 lapply 向量中混合了数字和字符变量 但是在 sql 语句中应用 as.numeric /as.character 似乎没有帮助

【问题讨论】:

  • 我知道现在已经很晚了,所以可能就像您在微睡眠中的感觉一样,您在写实际问题之前不小心按了 ENTER .... :-)
  • 这个问题很可能与assign(nam) &lt;- 可能不会做OP想要的事情有关。我认为您需要将所有内容都放在assign 调用中。

标签: r for-loop variable-assignment


【解决方案1】:

R 习惯用法是使用apply 类型函数而不是循环。这样做的效果是您的结果数据对象是list。在这种情况下,它将是data.frame 对象的列表。

类似于以下内容:

myQuery <- function(x){
  sqlQuery(channel,paste("Select myCol from myTable where myVal =", x, sep=""))
}

x <- c(3,9,12) 
t <- c("00","10","12")

myData <- lapply(c(t, x), myQuery)

然后您可以使用列表子集提取单个 data.frames:

myData[[1]]

编辑。关键是lapply 将采用单个向量作为输入。您的指令c(t, x) 将其输入组合成一个向量。因此,您不应该更改 myQuery - 它仍然只需要一个输入参数。

【讨论】:

  • 谢谢这工作正常。我在将其扩展到我有 2 个变量的实际情况时遇到问题,其中一个是字符
  • @pssguy 好吧,祝你好运。由于您没有提供有关问题的信息,因此我似乎无能为力。
  • 抱歉在我完成之前按下了输入按钮,我将编辑原始问题
  • 感谢您回答原始问题。我根据自己的需要选择了路线
【解决方案2】:

好吧,assign 函数需要名称和值作为参数:

assign(nam, sqlQuery(channel,paste("Select myCol from myTable where myVal =",x[i],sep="")))

输入 ?assign 了解更多...

【讨论】:

    【解决方案3】:

    你需要mapply:

    myData <- mapply(myQuery, t, x, SIMPLIFY=FALSE)
    

    但我认为更好的解决方案是首先准备查询:

    queries <- sprintf(
        "Select myCol from myTable where myTextVal='%s' and myVal=%i",
        t, x) # here I assume that x is integer, see ?sprintf for other formats
    queries
    [1] "Select myCol from myTable where myTextVal='00' and myVal=3" 
    [2] "Select myCol from myTable where myTextVal='10' and myVal=9" 
    [3] "Select myCol from myTable where myTextVal='12' and myVal=12"
    

    然后lapply 他们:

    myData <- lapply(queries, function(sql) sqlQuery(channel, sql))
    # could be simplified to:
    myData <- lapply(queries, sqlQuery, channel=channel)
    

    【讨论】:

    • 感谢 marek +1。 mapply 解决方案工作正常。我也会考虑你的替代方案。为什么你认为这更好?
    • @pssguy 可以在将查询发送到服务器之前对其进行验证。分离两个任务:准备查询和获取数据,如果同时完成所有任务,整体失败的机会就会增加。它还使您的代码更具可读性。
    猜你喜欢
    • 2020-12-12
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    相关资源
    最近更新 更多