Passing special character in DT Table - r

I am trying to escape special character "--" in column of DT table but formatPercentage is not letting this happen , manually passing formatPercentage(c(2,3,5)) is working and i want to make it dynamic. so i am looking for a solution through which column having "--" can be displayed in DT table.
I have tried ifelse but doesn't work , this code is just a part of my function.
df <- mtcars[1:6,1:5]
df$drat <- "--"
df$disp <- "--"
datatable(df, escape = FALSE) %>%
formatPercentage(2:5)
so the actual problem is I am trying to mask one column in my DT table output but formatPercentage not providing the require output. so i am looking for a solution .
My function is big thats why i am unable to create a reproducible example

You can exclude the columns which has '--' in them.
library(DT)
all_cols <- 2:5
format_cols <- setdiff(all_cols, which(colSums(df == '--') > 0))
datatable(df, escape = FALSE) %>% formatPercentage(format_cols)

Related

Multiline text in R dataframe

I'm trying to include a multiline text in a dataframe cell, however R keeps reading the \n as a next row, resulting in row mismatches. If i change the 'code' input to a simple string, the code works fine.
Defined dataframe:
df <- data.frame(
"Id" = character(),
"Name" = character(),
"Code" = character()
)
Adding new row:
NewRow <- data.frame(
"Id" = Id, # Simple string
"Name" = Name, # Simple string
"Code" = Code # Complex multiline string containing '#' and '\n' (10+ lines)
)
df <- rbind(df, NewRow)
Received error: Error in data.frame: arguments imply differing number of rows: 1, 0
Does anyone know how to get around this problem?
Many thanks in advance!
Maybe what you can try is to clean up the Code variable a bit, before adding it to the dataframe. In this sense, you can remove \n and # from the Code variable, and then add it inside the dataframe. For this you can use stringr and dplyr, to update the Code variable:
### Using the replace option:
Code <- Code %>%
str_replace_all("\\\n", "") %>%
str_replace_all("#", "")
### Using the remove option:
Code <- Code %>%
str_remove_all("\\\n") %>%
str_remove_all("#")

How to order a DataTable using a hidden column

I am rather new to R and I am trying to prepare an interactive data table using the DT package. My data contains numeric values, but some of these values are preceded by < or > sign. What I want is for my data table is to allow interactive sorting on the numeric values, regardless of whether there is a < or > sign in front of it. So for example >10, <5, 9, >8 should sort to <5, >8, 9, >10.
My initial approach for this was to duplicate the column containing the numeric values with < and > signs, to remove the < and > signs from this duplicate column, and to convert this data to numeric values to obtain a column with only the numeric values. What I then would like is to be able to order the data in the table on these numeric values, but I want to be able to do this when clicking the ordening button of the column containing the numeric values with the < and > signs. Therefore, I want to hide the column containing only the numeric values (since I do not want this column to be present in the table), but I want to somehow link the ordining function of the original column to this hidden column.
Here are some example data and a script in which I have already duplicated the column (b to c), removed the < and > signs, and converted it to numeric values to obtain the column c, which I have then hidden:
library(DT)
df <- data.frame(a=1:5, b=c('10','5.0','2.0','< 1.0','> 20'), c=c(10,5,2,1,20))
DT <- DT::datatable(df,
options = list(columnDefs =
list(list(visible=FALSE,
targets=3))))
DT
I have not been able to find a way to sort the data in the table on this hidden column c by using the sorting button of column b.
I have found that this should be possible in JavaScript: jQuery DataTables - Ordering dates by hidden column
However, I am not able to figure out how to do the same in R, either by using a suitable function in R, or by providing it in JavaScript using the JS() function.
Could anyone help me with this problem?
Here is a solution using render:
library(DT)
render <- c(
"function(data, type, row){",
" if(type === 'sort'){",
" return parseFloat(data.match(/\\d+\\.?\\d+/)[0]);",
" }else{",
" return data;",
" }",
"}"
)
df <- data.frame(
a = 1:5,
b = c('10','5.0','2.0','< 1.0','> 20')
)
DT <- datatable(df,
options = list(
columnDefs = list(
list(render = JS(render), type = "num", targets = 2)
)
)
)
DT
This solution does not require a hidden column.
Here's a way to do it. To get the "sorting key" use order.
library(DT)
# df <- data.frame(a=1:5, b=c('10','5.0','2.0','< 1.0','> 20'), c=c(10,5,2,1,20))
df <- data.frame(a = 1:5, b = c('10', '5.0', '2.0', '< 1.0', '> 20'))
df
#ONE APPROACH
df$c <-
stringr::str_replace(string = df$b,
pattern = "[<>]",
replacement = "") %>%
as.numeric()
#ANOTHER APPROACH
df$c <- gsub("[<>]", "", df$b) %>% as.numeric()
DT::datatable(df[order(df$c), -3], rownames = FALSE)
library(DT)
df <- data.frame(a=1:5, b=c('10','5.0','2.0','< 1.0','> 20'), c=c(10,5,2,1,20))
DT <- DT::datatable(df,
options = list(columnDefs =
list(list(visible=FALSE, targets=3),
list(orderData=3, targets=2)
)))
DT
Note: This answer is based on this one here, but DT now uses R indexing instead of JS indexing.

Filtering process not fetching full data? Using dplyr filter and grep

I have this log file that has about 1200 characters (max) on a line. What I want to do is read this first and then extract certain portions of the file into new columns. I want to extract rows that contain the text “[DF_API: input string]”.
When I read it and then filter based on the rows that I am interested, it almost seems like I am losing data. I tried this using the dplyr filter and using standard grep with the same result.
Not sure why this is the case. Appreciate your help with this. The code and the data is there at the following link.
Satish
Code is given below
library(dplyr)
setwd("C:/Users/satis/Documents/VF/df_issue_dec01")
sec1 <- read.delim(file="secondary1_aa_small.log")
head(sec1)
names(sec1) <- c("V1")
sec1_test <- filter(sec1,str_detect(V1,"DF_API: input string")==TRUE)
head(sec1_test)
sec1_test2 = sec1[grep("DF_API: input string",sec1$V1, perl = TRUE),]
head(sec1_test2)
write.csv(sec1_test, file = "test_out.txt", row.names = F, quote = F)
write.csv(sec1_test2, file = "test2_out.txt", row.names = F, quote = F)
Data (and code) is given at the link below. Sorry, I should have used dput.
https://spaces.hightail.com/space/arJlYkgIev
Try this below code which could give you a dataframe of filtered lines from your file based a matching condition.
#to read your file
sec1 <- readLines("secondary1_aa_small.log")
#framing a dataframe by extracting required lines from above file
new_sec1 <- data.frame(grep("DF_API: input string", sec1, value = T))
names(new_sec1) <- c("V1")
Edit: Simple way to split the above column into multiple columns
#extracting substring in between < & >
new_sec1$V1 <- gsub(".*[<\t]([^>]+)[>].*", "\\1", new_sec1$V1)
#replacing comma(,) with a white space
new_sec1$V1 <- gsub("[,]+", " ", new_sec1$V1)
#splitting into separate columns
new_sec1 <- strsplit(new_sec1$V1, " ")
new_sec1 <- lapply(new_sec1, function(x) x[x != ""] )
new_sec1 <- do.call(rbind, new_sec1)
new_sec1 <- data.frame(new_sec1)
Change columns names for your analysis.

How to define column specification for similarly named column with readr?

I have a data base with 250 columns and want to read only 50 of them instead of loading all of them then dropping columns with dplyr::select. I suppose I can do that using a column specification. I don't want to type the column specification manually for all those columns.
The 50 columns I want to keep have a common prefix, say 'blop', so I managed to manually change the column specification object I got from readr::spec_csv. I then used it to read my data file :
short_colspec <- readr::spec_csv('myfile.csv')
short_colspec$cols <- lapply(names(short_colspec$cols), function(name){
if (substr(name, 1, 4) == 'blop'){
return(col_character())
} else {
return(col_skip())
}
})
short_data <- read_csv('myfile.csv', col_types = short_colspec)
Is there a way to specify such a column specification with readr (or any other package) functions in a more robust way than what I did ?
using data.table's fread you can select columns you want to skip (=drop) or keep (=select)
#read first line of file to select which columns to keep
#adjust the strsplit-character here ';' according to your csv-type
keep_col <- readLines( "myfile.csv", n = 1L ) %>% strsplit( ";" ) %>% el() %>% grep( "blop", . )
#read file, only the desired columns
fread( "myfile.csv", select = keep_col )

Creating a list for search query from column using dbhydroR package

I am trying to create a list that I can copy into a search query for a function from a data.frame column. My output from the below code is in the format of :
‘C-484,''F-409,''S-18A,''G-850,''PB-632,'...etc.
But I need it to read
'C-484','F-409','S-18A','G-850','PB-632', ...etc.
There are 1,974 variables. How can I switch the placement of the last quote around each variable with the comma?
inactivestations <- read.csv("INACTIVE_WELLS.csv",header=TRUE)
#subset and make data.frame for only STATION (station names)
allstations_inactive <- inactivestations['STATION']
#not separated in a way that can be copied into a query
list(allstations_inactive$STATION)
#separated by commas and has quotes around each variable but commas inside quotes
test<-paste0(allstations_inactive$STATION, collapse="''",sep=",")
##separated by commas and has quotes around each variable but commas inside quotes
test1<-paste0(allstations_inactive$STATION, sep=",",collapse="''")
Thank you in advance
This approach works:
input <- c("C-484", "F-409", "S-18A", "G-850", "PB-632")
output <- paste0("'", input, "'", collapse = ",")
# cat(output)
# 'C-484','F-409','S-18A','G-850','PB-632'
So in your specific case it becomes:
test1 <- paste0("'", allstations_inactive$STATION, "'", collapse = ",")

Resources