Replace Text in Word documents using R and RDCOMClient - r

Using RDCOMClient, we can directly replace values in Excel cells, e.g.
range <- sheet$Range('A1')
range[['Value']] <- 1.2
In Word, Texts can be retrieved from the Text property of a range object, e.g.
word.doc[['Tables']][[1]]$Cell(2, 2)[['Range']][['Text']]
# "12/28/2022\r\a"
But while the Documentation of the range object says that the Text property can be used to retrieve or set the text of the range, this does not work in RDCOMClient:
word.doc[['Tables']][[1]]$Cell(2, 2)[['Range']][['Text']] <- "test"
# Error in word.doc[["Tables"]][[1]]$Cell(2, 2)[["Range"]][["Text"]] <- "test" :
target of assignment expands to non-language object
Is there a better way to edit the content of a cell or any other range/selection in Word?
If there is no way to do that, would selecting and Selection()$TypeText() or SearchReplace in the Range be more advisable?

It should work when you first get the Range object (from Word's viewpoint) and then set its Text property, e. g.:
library("RDCOMClient")
app <- COMCreate("Word.Application")
doc <- app$Documents()$Open('path_to_your_file.docx'))
## get the VBA object first:
the_range <- doc[['Tables']][[1]]$Cell(2, 2)[['Range']]
## assign its Text property:
the_range[['Text']] = "No cell is an island\n
Entire of itself;\n
Every cell needs a piece of content,\n
A part of the main."
doc$Save()

Related

Why do input functions like readline() and scan() include code when scanning for inputs? How to fix?

If I run,
input <- as.integer(scan(what = "integer"))
I get no problems, but
input <- scan(what = "integer")
#Anything here, including whitespace
Now input incudes the "#Anything here" as part of the input, and trying to as.integer() it gives me an NA. (If nmax=1, it automatically reads that as the input and doesn't allow any more.)
How is this preventable? What am I doing wrong?
Only works when you run the individual input line all by itself, give the input, then run the rest by itself. Should run code until input function is called, then give an input interface, THEN include the rest of the code. I am using RStudio.
In RStudio, use Source to read the input the way you want. Using Ctrl-Enter or Run simulates pasting it into the console (which means text following the scan() is assumed to be input).
So this works with Ctrl-Enter:
input <- scan(what = integer())
3
#Anything here, including whitespace
and the input ends up containing 3. (what should be an example of the type you want, not the name of it. So use integer() if you want an integer result.)
This works with Source:
input <- scan(what = integer())
#Anything here, including whitespace
and will prompt you to enter the number.

Fastest way to edit multiple lines of code at the same time

What is the best way to do the same action across multiple lines of code in the RStudio source editor?
Example 1
Let's say that I copy a list from a text file and paste it into R (like the list below). Then, I want to add quotation marks around each word and add a comma to each line, so that I can make a vector.
Krista Hicks
Miriam Cummings
Ralph Lamb
Jaylene Gilbert
Jordon Sparks
Kenna Melton
Expected Output
"Krista Hicks",
"Miriam Cummings",
"Ralph Lamb",
"Jaylene Gilbert",
"Jordon Sparks",
"Kenna Melton"
Example 2
How can I add missing parentheses on multiple lines. For example, if I have an if statement, then how can I add the missing opening parentheses for names on line 1 and line 4.
if (!is.null(names pattern))) {
vec <- FALSE
replacement <- unname(pattern)
pattern[] <- names pattern)
}
Expected Output
if (!is.null(names(pattern))) {
vec <- FALSE
replacement <- unname(pattern)
pattern[] <- names(pattern)
}
*Note: These names are just from a random name generator.
RStudio has support for multiple cursors, which allows you to write and edit multiple lines at the same time.
Example 1
You can simply click Alt on Windows/Linux (or option on Mac) and drag your mouse to make your selection, or you can use Alt+Shift to create a rectangular selection from the current location of the cursor to a clicked position.
Example 2
Another multiple cursor option is for selecting all matching instances of a term. So, you can select names and press Ctrl+Alt+Shift+M. Then, you can use the arrow keys to move the cursors to delete the space and add in the parentheses.

Dynamic String Manipulation in Knime

I want to dyanamically change my URL at runtime for which I did string manipulations in R and it worked with this script:
x <- 'https://news.google.com/search?q='
var <- 'NREGA'
z <- '&hl=en-IN&gl=IN&ceid=IN%3Aen'
url <- paste0(x, var,z, collapse = '')
url
Now I want to change this variable var dynamically and the value for var needs to be retrieved from a knime node which can then be used in url. In my case it's the table creator node in knime to get this value but I'm not able to assign it to var.
Kindly suggest any knime node by which the value for 'var' can be obtained and then be used in 'R snippet' node in knime, and can be used in manipulating the url.
The first line of the code in your image is
knime.in <- knime.flow.in[["NREGA"]]
The expression knime.flow.in[["NREGA"]] in an R script node gets you the value of the flow variable named NREGA.
You probably don't want to assign that value to knime.in as that's the R dataframe containing the table from the input port of the KNIME node. Either you want to use that table - in which case don't overwrite it - or you don't, in which case just use the R Source (Table) node which has no input port.
Later on in your code you have the line
var <- knime.flow.in[["NREGA"]]
which should assign the flow variable value to the R variable var. If that isn't working the way you want, please edit your question to better describe what the problem is.

Dynamic variable names in rvest

I am trying to set values with rvest for dynamic field names. So I retrieve the field name with the code below. f.account is a character of length one, containing a dynamic field name like OCmaCMFgHij
library(rvest)
url <- "https://sv01.net-housting.de/user/index.php"
sp.session <- html_session(url)
f0 <- html_form(sp.session)
f.account <- f0[[2]][['fields']][[1]]$name
Note: This is a little arbitrary example since f.account is not really dynamic in this case, but will always have the value username.
Now I want to set a fixed value to the field in the form with smth like this:
f1 <- set_values(f0, UQ(rlang::sym("f.account")) = "MyAccountName" ))
I tried to use the .dot statement or setNames as described here, but I have failed so far.

readline is considering every record in the spreadsheet as a new line [R]

I am trying to create a function that will calculate the frequency count of keywords using TM package. The function works fine if the text pasted from readline is on free form text without a new line. The problem is, when I paste a bunch of text copied from a spreadsheet, readline considers it as a new line.
keyword <- function() {
x <- readline(as.character('Input text here: '))
x <- Corpus(VectorSource(x))
...
tdm <- TermDocumentMatrix(x)
...
tdm
}
Here's the full code: https://github.com/CSCDataAnalytics/PM-Analysis/blob/master/Keyword.R
How can I prevent this from happening or at least consider a bunch of text of every row from the spreadsheet as one vector only?
If I'm understanding you correctly, the problem is when the user pastes the text from another application: the newline is causing R to stop accepting the subsequent lines.
One technique (fragile as it may be) is to look for a specific line, such as an empty line "" or a period ".". It's a little fragile because now you need (1) assurance that the data will "never" include that as a whole line, and (2) it is easily appended by the user.
Try:
endofinput <- ""
totalstr <- ""
while(! endofinput == (x <- readline('prompt (empty string when done): ')))
totalstr <- paste(totalstr, x)
In this case, the empty string is the catch, and when the while loop is done, totalstr contains all input separated by a space (this can be changed in the paste function).
NB: one problem with this technique is that it is "growing" the vector totalstr, which will eventually cause performance penalties (depending on the size of the input data): every loop iteration, more memory is allocated and the entire string is copied plus the new line of text. There are more verbose ways to side-step this problem (e.g., pre-allocate a vector larger than your anticipated input data), but if you aren't anticipated 1000s of lines then you may be able to accept this naive programming for simplicity.
Another option would be to have the user save the data to a text file and use file.choose() and readLines() to get your data.
Try collapsing the data into a single string after using readline
x <- paste(readline(as.character('Input text here: ')), collapse=' ')

Resources