我在函数有一些sql代码的数据框上应用函数时遇到问题。考虑以下虚拟数据框:
df <- read.table(header=T, text='
ID
20
21
22
')
当我尝试这样做时(在我建立与数据库的连接并且它起作用之后):
df<-transform(df, name="") #create another column name
df$name<-my_name(df$ID) #apply the function my_name on df$ID
my_name<-function(id)
{
query = "select first_name from my_table WHERE id= "
query = paste(query, id, sep="")
rs = dbSendQuery(my_db, query) #my_db was already established
fname<- fetch(rs)[1,1]
return (fname)
}
对于相同的ID 20(数据帧中的第一个),我得到了相同的结果。
为什么呢? (...记录21是迈克,22是彼得)
结果不正确:
ID name
1 20 John
2 21 John
3 22 John
答案 0 :(得分:1)
尝试:
df$name <- sapply(df$ID, my_name)
您每次都会向函数发送整个ID字段,看起来该函数只返回第一个值。
您还可以修改SQL查询以使用IN
,然后您可以发送多个ID,并在一个连接中获取正确的结果集。
我多次使用以下sytax:
query <- "select first_name from my_table WHERE id IN (%s)"
query <- sprintf(query, paste0("\"", id, "\"", collapse = ","))
答案 1 :(得分:1)
如果您修改功能,只需在构建query
后停止并返回该功能,您就会看到:
my_name(df$ID)
[1] "select first_name from my_table WHERE id= 20" "select first_name from my_table WHERE id= 21"
[3] "select first_name from my_table WHERE id= 22"
事情肯定是不对的。您已经创建了一个包含三个单独查询的字符向量。 dbSendQuery
没有被矢量化(你也不会真的想要它),所以它只是运行第一个。
更一般地说,我认为您尝试使用的SQL是错误的。您可能想要一个看起来更像的查询:
select first_name from my_table WHERE id IN (20,21,22)
请注意IN
子句。这需要做更多这样的事情:
query <- "select first_name from my_table WHERE id in "
query <- paste(query, paste0("(",paste(id,collapse = ","),")"), sep="")