I am trying to get two strings that contain quotations ("") combined as a character/string vector or with R function paste so I can plug the result in the argument x of writeFormula in openxlsx package.
An example is like this
paste('HYPERLINK("file)',':///"&path!$C$1&TRIM(MID(CELL("filename",B',sep="")
and I hope that it should produce the result like this
HYPERLINK("file:///"&path!$C$1&TRIM(MID(CELL("filename",B
but it actually produces the result with a backslash in front of the ":
[1] "HYPERLINK(\"file):///\"&path!$C$1&TRIM(MID(CELL(\"filename\",B"
I have searched for many potential solutions like replace paste with cat or add noquote function in front of paste but the output is not a character vector. Functions like toString or as.character could convert these results to strings but the backslash comes back as well.
Really appreciate any helps with this. Thanks.
There are no backslashes in p. The backslashes you see are just how R displays a quote (so that you know that the quote is part of the string and not the ending delimiter) but are not in the string itself.
p <- paste0('HYPERLINK("file)', ':///"&path!$C$1&TRIM(MID(CELL("filename",B')
p
## [1] "HYPERLINK(\"file):///\"&path!$C$1&TRIM(MID(CELL(\"filename\",B"
# no backslashes are found in p
grepl("\\", p, fixed = TRUE)
## [1] FALSE
noquote(p), cat(p, "\n") or writeLines(p) can be used to display the string without the backslash escapes:
noquote(p)
## [1] HYPERLINK("file):///"&path!$C$1&TRIM(MID(CELL("filename",B
cat(p, "\n")
## HYPERLINK("file):///"&path!$C$1&TRIM(MID(CELL("filename",B
writeLines(p)
## HYPERLINK("file):///"&path!$C$1&TRIM(MID(CELL("filename",B
One can see the individual characters separated by spaces like this. We see that there are no backslashes:
do.call(cat, c(strsplit(p, ""), "\n"))
## H Y P E R L I N K ( " f i l e ) : / / / " & p a t h ! $ C $ 1 & T R I M ( M I D ( C E L L ( " f i l e n a m e " , B
As another example here p2 contains one double quote and has a single character in it, not 2:
p2 <- '"'
p2
## [1] "\""
nchar(p2)
## [1] 1
Related
I am trying to pad a character with a space using sprintf() (but any base R alternative is would be fine).
It works as expected for letter "a" but for "β" it won't work:
sprintf('% 2s', 'a')
#> [1] " a"
sprintf('% 2s', 'β')
#> [1] "β"
sprintf('% 3s', 'β')
#> [1] " β"
I guess it has to do with the fact that it takes two bytes (i.e., two sprintf's "characters") to represent the "β" string... but so, I could I change my code to make it work and pad with spaces in a way that "β" is understood as one character (i.e., one-visible character).
Convert the string to native first. This worked for me on Windows but not on https://rdrr.io/snippets/ which reports its .Platform$os.type as unix.
s <- 'β'; n <- 3 # inputs
sprintf("%*s", n, enc2native(s)) # or hard code the 3 and drop n
## [1] " ß"
Alternately use paste0 or substring<- with strrep or convert the string to X's, perform the sprintf and then convert back. These worked on Windows and on https://rdrr.io/snippets/ .
# 2
paste0(strrep(' ', n - nchar(s)), s)
## [1] " β"
# 3
`substring<-`(strrep(" ", n), n - nchar(s) + 1, n, s)
## [1] " ß"
# 4
sub("X+", s, sprintf("%*s", n, strrep("X", nchar(s))))
## [1] " β"
I am trying to get the number of open brackets in a character string in R. I am using the str_count function from the stringr package
s<- "(hi),(bye),(hi)"
str_count(s,"(")
Error in stri_count_regex(string, pattern, opts_regex = attr(pattern,
: ` Incorrectly nested parentheses in regexp pattern.
(U_REGEX_MISMATCHED_PAREN)
I am hoping to get 3 for this example
( is a special character. You need to escape it:
str_count(s,"\\(")
# [1] 3
Alternatively, given that you're using stringr, you can use the coll function:
str_count(s,coll("("))
# [1] 3
You could also use gregexpr along with length in base R:
sum(gregexpr("(", s, fixed=TRUE)[[1]] > 0)
[1] 3
gregexpr takes in a character vector and returns a list with the starting positions of each match. I added fixed=TRUE in order to match literals.length will not work because gregexpr returns -1 when a subexpression is not found.
If you have a character vector of length greater than one, you would need to feed the result to sapply:
# new example
s<- c("(hi),(bye),(hi)", "this (that) other", "what")
sapply((gregexpr("(", s, fixed=TRUE)), function(i) sum(i > 0))
[1] 3 1 0
If you want to do it in base R you can split into a vector of individual characters and count the "(" directly (without representing it as a regular expression):
> s<- "(hi),(bye),(hi)"
> chars <- unlist(strsplit(s,""))
> length(chars[chars == "("])
[1] 3
I want to count occurrence(s) of each character in the following string and output the result as [character] [number] [character] [number] format, lowercase and sort by the character.
"Hello World !"
d 1 e 1 h 1 l 3 o 2 r 1 w 1 ! 1
Solution in base R. First we split the string using strsplit() and empty string "" as split. Also unlist and sort at the same time. For good measure, we define a vector of strings we do not want in our output; it seems you don't count the space " " as a character. This has to be defined. Next, a little package pasted in paste0()'s. First, use lapply on the uniques of characters to count each occurance. Then, paste this with the respective string (and an equal sign). Last, collapse the resulting string with commas.
Here is the code:
example_string = "Hello World!"
unwanted_chars = c(" ")
split_string = sort(unlist(strsplit(example_string, "")))
split_string = split_string[split_string %in% unwanted_chars]
paste0(paste0(unique(split_string), " = ",
unlist(lapply(unique(split_string),
function(x) sum(x == unlist(split_string))))),
collapse = ", ")
The long line looks a bit ugly, if you want to undestand it, unwrap it layer by layer.
#Calbers is right that strsplit is the right way to go, but it can be achieved using a one-liner:
examples = c("Hello World!", "Lorem ipsum")
lapply(strsplit(examples, ""), table)
i.e. split each element of the examples using the null split "" and then lapply the table function to it. With a single example it is:
table(strsplit(examples, "")[[1]])
i.e. we take the first element from the list outputted by strsplit.
How similar is print command in R to printf in C? I want to write a command printf(%s, variable) in R? Any suggestions how to do that?
My code:
v <- "abc"
print(sprintf(%s, v)
Error: unexpected input in "print(sprintf(%s, v)"
You have two errors:
R> v <- "abc"
R> print(sprintf("%s", v))
[1] "abc"
The first was to not write the format string as a string in quotes. The second was a missing closing parenthesis.
But you probably want this as an argument to cat() where you want to end a newline in one of two places:
R> cat(sprintf("%s", v), "\n")
abc
R> cat(sprintf("%s\n", v))
abc
R>
Whenever I format a table as such:
example <- sample(LETTERS, replace = T)
format(table(example), scientific = T)
The numbers become characters. How can I tell format() my object is numeric without resorting to as.numeric()? I can't find any such parameters in the function's help page. It says that format() objects are usually numeric, so I guess I'm missing some basic command.
My real data looks like this:
> xtabs(...)
PRU/DF PSU/ILH PSU/JFA PSU/MCL PSU/SRM PSU/ULA
1.040771e+01 0.000000e+00 2.280347e-01 0.000000e+00 0.000000e+00 8.186240e+00
PSU/URA PSU/VGA PU/AC PU/AM PU/AP PU/BA
0.000000e+00 1.534169e+01 8.184747e+01 1.410106e+01 1.028717e+01 1.099289e+00
PU/GO PU/MA PU/MG PU/MT PU/PA PU/PI
0.000000e+00 4.369910e+01 5.350849e+00 0.000000e+00 4.706721e-01 0.000000e+00
I want to have the console print the numbers prettier so my co-workers don't have a heart attack. This is what I've come up with:
> format(xtabs(...), scientific = F, digits = 1)
PRU/DF PSU/ILH PSU/JFA PSU/MCL PSU/SRM PSU/ULA PSU/URA PSU/VGA
"10.4077" " 0.0000" " 0.2280" " 0.0000" " 0.0000" " 8.1862" " 0.0000" "15.3417"
PU/AC PU/AM PU/AP PU/BA PU/GO PU/MA PU/MG PU/MT
"81.8475" "14.1011" "10.2872" " 1.0993" " 0.0000" "43.6991" " 5.3508" " 0.0000"
PU/PA PU/PI PU/RO PU/RR PU/TO PRU/RJ PSU/CPS PSU/NRI
" 0.4707" " 0.0000" "40.6327" "10.3247" " 0.0000" "10.9644" " 0.0000" "55.4122"
I'd like to get rid of those quotes so the data looks better on the console.
The format function returns character vectors with the numbers now "formatted" per your specifications. If you convert the result back to numbers then any formatting is now lost. I think your problem may be rather the difference between creating the formatted output and printing the formatted output. When you create an object, but don't do anything with it, the object is automatically printed using default arguments, one of the defaults is to put quotes around the character strings. If you don't want the quotes then just call print yourself and tell it to not include the quotes:
> example <- sample(LETTERS, replace = T)
> print(format(table(example), scientific = T), quote=FALSE)
example
B E F G H J K L Q S T U W X Z
1 1 1 2 1 2 3 1 1 1 3 1 1 5 2
If your main goal is to not use scientific notation then you should look at the zapsmall function which will turn extremely small values (often the culprit in switching to scientific notation) into zeros. Or do options(scipen=5) (or some other value than 5) which will reduce the likelihood of switching to scientific notation in subsequent printing.
Format returns character vectors, so this is in general to be expected. Your problem, I think, results from the fact that the "format" representation of an integer vector c( 1, 2, 3) is "1" "2" "3", whereas the representation of a numeric (real) vector c( 1, 2, 3 ) is "1e+00" "2e+00" "3e+00".
Consider the following:
format( 1:10 )
format( 1:10, scientific= TRUE )
format( as.numeric( 1:10 ), scientific= TRUE )
Therefore, try
format( as.numeric( table( example ) ), scientific= TRUE )
Unfortunately, you cannot omit the as.numeric, since table generates integer values, and you need real.
From your comments on #January's answer, it appears you're just looking for c(table(example)).
Here's a solution I've found:
View(format(xtabs(...), scientific = F, digits = 1))
The table will appear in another window instead of inside the console, like I originally wanted, but it solves my problem of quickly showing pretty data without resorting to long commands. More elegant solutions are welcome!