I have a list of objects that I would like to concatenate into a string. This will ultimately be used to construct a SQL statement.
library(purrr)
test <- list(key = "value", key1 = "value1", key2 = "value2")
> test
$key
[1] "value"
$key1
[1] "value1"
$key2
[1] "value2"
map2(names(test), test, ~paste(.x, "=", .y)) %>%
reduce(c) %>%
paste0(collapse = ", ")
This gives the desired result, but wondering if I'm missing a more obvious solution.
[1] "key = value, key1 = value1, key2 = value2"
You can use paste
You can obtain the same result by only using paste:
paste(names(test), test, sep = " = ", collapse = ", ")
Output:
[1] "key = value, key1 = value1, key2 = value2"
Hope this helps.
Or we can convert to a data.frame and paste with do.call
do.call(paste, c(stack(test)[2:1], sep=" = ", collapse=", "))
#[1] "key = value, key1 = value1, key2 = value2"
Related
I was trying to create a status bar in my for loop, but the status remains at 0%. I'm not sure what the issue could be.
n <- length(unique(mu_ut$AnimalID))
pb <- txtProgressBar(min = 0, max = n, style = 3)
for(i in unique(mu_ut$AnimalID)){
AnID <- paste("AnID", i, sep = ".")
assign(AnID, mu_ut[mu_ut$AnimalID == i,])
dbWriteTable(conn = db, name = AnID, value = mu_ut[mu_ut$AnimalID == i,],
field.types = c(DateAndTime = "DATETIME",
AnimalID = "CHAR",
Species = "CHAR",
Sex = "CHAR",
CurrentCohort = "CHAR",
BirthYear = "DATE",
CaptureUnit = "CHAR",
CaptureSubunit = "CHAR",
CaptureArea = "CHAR"), overwrite = TRUE)
Sys.sleep(1)
setTxtProgressBar(pb, i)
}
Is it a problem with the "i" argument in the setTxtProgressBar function?
Thank you in advance.
The issue is that setTxtProgressBar needs its value to be in the sequence min=0 to max=n, as set in your txtProgressBar. Since i is really one of the unique values within mu_ut$AnimalID, even if it is an integer, it is not clear that it is also in the range 0:n.
Try this.
ids <- unique(mu_ut$AnimalID)
pb <- txtProgressBar(min = 0, max = length(ids), style = 3)
for (ind in seq_along(ids)) {
id <- ids[ind]
AnID <- paste("AnID", id, sep = ".")
assign(AnID, mu_ut[mu_ut$AnimalID == id,])
dbWriteTable(conn = db, name = AnID, value = mu_ut[mu_ut$AnimalID == id,],
field.types = c(DateAndTime = "DATETIME",
AnimalID = "CHAR",
Species = "CHAR",
Sex = "CHAR",
CurrentCohort = "CHAR",
BirthYear = "DATE",
CaptureUnit = "CHAR",
CaptureSubunit = "CHAR",
CaptureArea = "CHAR"), overwrite = TRUE)
Sys.sleep(1)
setTxtProgressBar(pb, ind)
}
(This is very similar to #CareyCaginalp's comment.)
I am trying to create a SQLite table for each factor that I have in a R dataframe. I have created a for loop in an attempt to accomplish this, but when I include the dWriteTable() function it gives me an error. I believe it might have something to do with the "argument" but I can't say for certain.
Here is the code I currently have with the for loop:
# Connects to the database##
mydb <- dbConnect(RSQLite::SQLite(), "../Output/all_data.sqlite")
#Reads the selected table in database
mu_ut <- dbReadTable(mydb, "mu_ut")
for(i in unique(mu_ut$AnimalID)){
AnID <- paste("AnID", i, sep = ".")
dfname <- assign(AnID, mu_ut[mu_ut$AnimalID == i,])
dbWriteTable(conn = mydb, name = dfname, value = dat_csv,
field.types = c(DateAndTime = "DATETIME",
AnimalID = "CHAR",
Species = "CHAR",
Sex = "CHAR",
CurrentCohort = "CHAR",
BirthYear = "DATE",
CaptureUnit = "CHAR",
CaptureSubunit = "CHAR",
CaptureArea = "CHAR"))
}
I get the error message when I run it:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘dbWriteTable’ for signature ‘"SQLiteConnection", "data.frame", "data.frame"’
Any help would be appreciated!
Thank you!
When using dbWriteTable :
name is a character string giving the name of the table.
value is a dataframe with the values to write into the table
Try:
dbWriteTable(conn = mydb, name = AnID, value = mu_ut[mu_ut$AnimalID == i,],
field.types = c(DateAndTime = "DATETIME",
AnimalID = "CHAR",
Species = "CHAR",
Sex = "CHAR",
CurrentCohort = "CHAR",
BirthYear = "DATE",
CaptureUnit = "CHAR",
CaptureSubunit = "CHAR",
CaptureArea = "CHAR"))
I am trying to create 2 variable from a string in the cell. cell string is "Mr Jonhattan Smith Sun". Value1 I want as "Jonhattan" and value2 as "Smith Sun". I have the following codes but doesn't seem to work properly. any Help Please
value1 = Left(ThirdTable.Rows(10).Cells(2).Range.text, Len(ThirdTable.Rows(10).Cells(2).Range.text) - InStrRev(ThirdTable.Rows(10).Cells(2).Range.text, " "))
value2 = Right(ThirdTable.Rows(10).Cells(2).Range.text, Len(ThirdTable.Rows(10).Cells(2).Range.text) - InStrRev(ThirdTable.Rows(10).Cells(2).Range.text, " ") + 1)
Try:
ss = Split(ThirdTable.Rows(10).Cells(2).Range.Text, " ")
Value1 = ss(1)
Value2 = ss(2) & " " & ss(3)
Given that
ThirdTable.Rows(10).Cells(2).Range.Text Gives you Mr Jonhattan Smith Sun
Demo:
If that Weird Letter comes up like in the Demo use:
Value2 = ss(2) & " " & Left(ss(3), Len(ss(3)) - 1)
I am attempting to write a dataframe using R to Teradata. The dataframe is wide in format (over 100 columns) and writing to Teradata implies declaring both the name and class of each variable. Note that the below data is just serving as an example.
iris$integerRandom <- seq_along(iris$Sepal.Length)
iris$Dates <- seq.Date(as.Date("2018-01-01"), by = "d", length.out = nrow(iris))
iris$Dates2 <- seq.Date(as.Date("2019-01-01"), by = "d", length.out = nrow(iris))
iris$Species <- as.character(iris$Species)
iris$characterRandom <- sample(letters, nrow(iris), replace = TRUE)
## Getting Numeric and Integer Names first
names_num <- names(iris)[which(sapply(iris, class) %in% c("integer", "numeric"))]
names_date <- names(iris)[which(sapply(iris, class) %in% "Date")]
names_character <- names(iris)[which(sapply(iris, class) %in% "character")]
## Generating variable names with corresponding variable types
paste(gsub("varchar(300)", '"varchar(300)"', gsub(",", " = varchar(300), ", toString(names_character))), "varchar(300)", sep = " = ")
paste(gsub(",", " = date", toString(names_date)), " = date")
paste(gsub("varchar(300)", '"float"', gsub(",", " = float, ", toString(names_num))), "float", sep = " = ")
Ideally, I would like the desired output to say
Species = "varchar(300)", characterRandom = "varchar(300)", and so forth. Note that the order in which the variables is important as the order matters when declaring the names and the types to Teradata (or SQL in this case) the code will probably work for both tools. So the order of the variable names along with
Sepal.Length and end with characterRandom.
I have the following zoo object (res)
column1 column2 column3
2015-12-30 3.2735 2.3984 1.1250
2015-12-31 2.5778 1.8672 1.1371
2016-01-01 3.3573 2.4999 1.1260
2016-01-04 3.3573 2.4999 1.1463
and I would like to produce a vectorized update query.
UPDATE table SET column1=3.2735, column2=2.3984, column3=1.1250 WHERE dt = '2015-12-30';
UPDATE table SET column1=2.5778, column2=1.8672, column3=1.1371 WHERE dt = '2015-12-31';
etc.
I was able to do something similar previously for an INSERT query
sColumns <- paste0("dt, index, ", paste0(colnames(res), collapse=", "))
sValues = apply(data.frame(paste0("'", index(res), "'"), paste0("'", index, "'"), coredata(res)),
1 , paste, collapse = ",")
sql <- paste0("INSERT INTO table (", sColumns, ") VALUES (", sValues, ")")
which was considerably easier because all column names were grouped, and all values were grouped. For an UPDATE query, I have to combine alternately columns and fields.
So far, I have the following:
sColumns <- paste0(colnames(res), "=")
tmp <- paste(c(matrix(c(sColumns, res[1, ]), 2, byrow = T)), collapse = ", ")
tmp <- gsub("=, ", "=", tmp)
Which produces (for one row), output like:
[1] "column1=3.2735, column2=2.3984, column3=1.125"
Can anyone provide guidance as to how I can use something like apply() to do this for all rows of 'res'?
1) Try this:
library(zoo)
sapply(1:nrow(res), function(i) paste0(
"UPDATE table SET ",
toString(paste0(names(res), "=", coredata(res)[i, ])),
" WHERE dt='", time(res)[i], "'"))
giving the following character vector:
[1] "UPDATE table SET column1=3.2735, column2=2.3984, column3=1.125 WHERE dt='2015-12-30'"
[2] "UPDATE table SET column1=2.5778, column2=1.8672, column3=1.1371 WHERE dt='2015-12-31'"
[3] "UPDATE table SET column1=3.3573, column2=2.4999, column3=1.126 WHERE dt='2016-01-01'"
[4] "UPDATE table SET column1=3.3573, column2=2.4999, column3=1.1463 WHERE dt='2016-01-04'"
2) And a variation giving the same result:
sapply(unname(split(res, time(res))), function(z) paste0(
"UPDATE table SET ",
toString(paste0(names(z), "=", z)),
" WHERE dt='", time(z), "'"))
Note 1: If your table is not too large then you could alternately consider reading it into R, performing the update in R and then writing it back.
Note 2: Here is the input shown reproducibly:
Lines <- "Date column1 column2 column3
2015-12-30 3.2735 2.3984 1.1250
2015-12-31 2.5778 1.8672 1.1371
2016-01-01 3.3573 2.4999 1.1260
2016-01-04 3.3573 2.4999 1.1463"
library(zoo)
res <- read.zoo(text = Lines, header = TRUE)
Is this what you want?
foo <- apply(res,1, function(x){
sprintf("%s = %f", names(x),x)
})
lapply(colnames(foo), function(nn) {
sprintf("UPDATE table SET %s WHERE dt = \'%s\'",
paste(foo[,nn], collapse=","),
nn)
})
which gives:
[[1]]
[1] "UPDATE table SET column1 = 3.273500,column2 = 2.398400,column3 = 1.125000 WHERE dt = '2015-12-30'"
[[2]]
[1] "UPDATE table SET column1 = 2.577800,column2 = 1.867200,column3 = 1.137100 WHERE dt = '2015-12-31'"
[[3]]
[1] "UPDATE table SET column1 = 3.357300,column2 = 2.499900,column3 = 1.126000 WHERE dt = '2016-01-01'"
[[4]]
[1] "UPDATE table SET column1 = 3.357300,column2 = 2.499900,column3 = 1.146300 WHERE dt = '2016-01-04'"