How to get python to add and divide multiple variables? - math

Greetings fellow python programmers. I am building a raspberry pi project that is designed to use moisture sensors in my garden. I have the program designed to take readings for thirty seconds and then average them all into one number. It uses four sensors and runs off of python3.5 The sensors all work just fine, but I'm having a problem getting python to do the math to average the inputs. I think it is adding the variables, but it doesn't seem to be dividing them. Here is the code:
TEST_SOIL()
outpuT = str(output)
print("Moisture:", outpuT)
GPIO.output(buzzer,GPIO.HIGH)
sleep(0.1) # Delay in seconds
GPIO.output(buzzer,GPIO.LOW)
sleep(0.1)
GPIO.output(buzzer,GPIO.HIGH)
sleep(0.1) # Delay in seconds
GPIO.output(buzzer,GPIO.LOW)
print("TESTING SOIL")
o1 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o2 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o3 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o4 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o5 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o6 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o7 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o8 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o9 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o10 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o11 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o12 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o13 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o14 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o15 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o16 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o17 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o18 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o19 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o20 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o21 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o22 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o23 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o24 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o25 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o26 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o27 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o28 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o29 = (output + output2 + output3 + output4/4)
sleep(1)
TEST_SOIL()
o30 = (output + output2 + output3 + output4/4)
sleep(1)
o = (o1 + o2 + o3 + o4 + o5 + o6 + o7 + o8 + o9 + o10 + o11 + o12 + o13 + o14 + o15 + o16 + o17 + o18 + o19 + o20 + o21 + o22 + o23 + o24 + o25 + o26 + o27 + o28 + o29 + o30)
o = (o/30)
If anyone is wondering what "TEST_SOIL()" is, that is my own function I created earlier in the program. It is defined here:
def TEST_SOIL():
output = analogInput(0) # Reading from CH0
output = interp(output, [0, 1023], [100, 0])
output = int(output)
output = (output - 12.5)
output2 = analogInput(1) # Reading from CH0
output2 = interp(output2, [1, 1023], [100, 1])
output2 = int(output2)
output2 = (output2 - 12.5)
output3 = analogInput(2) # Reading from CH0
output3 = interp(output3, [2, 1023], [100, 2])
output3 = int(output3)
output3 = (output3 - 12.5)
output4 = analogInput(3) # Reading from CH0
output4 = interp(output4, [3, 1023], [100, 3])
output4 = int(output4)
output4 = (output4 - 12.5)
I need to metion that this code also controls a small buzzer to clear up any confusion with the "GPIO.output(buzzer,high/low)" text. If anyone can tell me how to fix this code that would be great.
:)

I took the liberty of refactoring your code a bit.
I assume the 4 different analog reads need to be as such and didn't touch them, but otherwise...
test_soil now returns a 4-tuple of the readings.
average_output() takes any iterable of numbers to average over.
beep() beeps the buzzer.
main calls the above bits in a loop, gathering values into an array, which it then finally averages.
def TEST_SOIL():
output = analogInput(0) # Reading from CH0
output = interp(output, [0, 1023], [100, 0])
output = int(output)
output = output - 12.5
output2 = analogInput(1) # Reading from CH0
output2 = interp(output2, [1, 1023], [100, 1])
output2 = int(output2)
output2 = output2 - 12.5
output3 = analogInput(2) # Reading from CH0
output3 = interp(output3, [2, 1023], [100, 2])
output3 = int(output3)
output3 = output3 - 12.5
output4 = analogInput(3) # Reading from CH0
output4 = interp(output4, [3, 1023], [100, 3])
output4 = int(output4)
output4 = output4 - 12.5
return (output, output2, output3, output4)
def average_output(o):
return sum(o) / len(o)
def beep():
GPIO.output(buzzer, GPIO.HIGH)
sleep(0.1) # Delay in seconds
GPIO.output(buzzer, GPIO.LOW)
def main():
ao = average_output(TEST_SOIL())
print("Initial Moisture:", ao)
beep()
beep()
print("TESTING SOIL")
values = []
for x in range(30):
values.append(average_output(TEST_SOIL()))
sleep(1)
final_average = average_output(values)
print("Final Moisture:", final_average )

change (output + output2 + output3 + output4/4) to (output + output2 + output3 + output4)/4
Your code first divides by four the last variable (ouotput4) and then adding them together.
(Edit: forgot there is no average function for list. sorry. You can use sum() for some list and then divide it by len() of this list)

this might be able to fix ur code and tidy it a bit
instead of writing the same thing again u can use a for loop to make the job easier
for step in range(30):
TEST_SOIL()
op_avg = (output1 + output2 + output3 + output4) / 4.0
op = op + op_avg
sleep(1)
op = op/30
hope it helps

Related

Solve the recursion

I am trying to solve the recursion T (n) = T (n/5) + n^2
and I cant figure out after following step.
T (k) = T (k/5) + k^2
= (T(k/25) + k^2/25) + k^2
= (T(k/625) + k^2/625) + k^2/25 + k^2
= T(1) + … + k^2/625 + k^2/25 + k^2
= k^2+ k^2/25+ k^2/625 +…+ T(1)
= k^2(1 + 1/25 + 1/625 + …)

Sum up some factors total counts in R

Very new to R!
I have a survey with people answering from 0 to 10. I want to add up how many people were <= 6. How many 7 and 8. How many >=9.
I had to turn the questions (Return, Trustworthy...) into a factors to make a ggplots with 1 to 10 on the x axis.
uk_super_q<-read.csv("SUPR_Q_UK.csv", header = TRUE)
uk_super_q.Return <- as.factor(uk_super_q$Return)
uk_super_q.Trustworthy <- as.factor(uk_super_q$Trustworthy)
uk_super_q.Credible <- as.factor(uk_super_q$Credible)
uk_super_q.Trustworthy <- as.factor(uk_super_q$Trustworthy)
uk_super_q.Clean.and.Simple <- as.factor(uk_super_q$Clean.and.Simple)
uk_super_q.Easy.to.use <- as.factor(uk_super_q$Easy.to.use)
uk_super_q.Attractive <- as.factor(uk_super_q$Attractive)
uk_super_q.NPS <- as.factor(uk_super_q$NPS)
uk_super_q$Return <- as.factor(uk_super_q$Return)
ggplot(uk_super_q, aes(x = Return)) +
geom_bar() +
xlab("Return") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Return)
uk_super_q$Easy.Nav <- as.factor(uk_super_q$Easy.Nav)
ggplot(uk_super_q, aes(x = Easy.Nav)) +
geom_bar() +
xlab("Easy.Nav") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Trustworthy)
uk_super_q$Credible <- as.factor(uk_super_q$Credible)
ggplot(uk_super_q, aes(x = Credible)) +
geom_bar() +
xlab("Credible") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Credible)
uk_super_q$Attractive <- as.factor(uk_super_q$Attractive)
ggplot(uk_super_q, aes(x = Attractive)) +
geom_bar() +
xlab("Attractive") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Attractive)
uk_super_q$Trustworthy <- as.factor(uk_super_q$Trustworthy)
ggplot(uk_super_q, aes(x = Trustworthy)) +
geom_bar() +
xlab("Trustworthy") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Trustworthy)
uk_super_q$Clean.and.Simple <- as.factor(uk_super_q$Clean.and.Simple)
ggplot(uk_super_q, aes(x = Clean.and.Simple)) +
geom_bar() +
xlab("Clean.and.Simple") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Clean.and.Simple)
uk_super_q$Easy.to.use <- as.factor(uk_super_q$Easy.to.use)
ggplot(uk_super_q, aes(x = Easy.to.use)) +
geom_bar() +
xlab("Easy.to.use") +
ylab("Total Count") +
labs(fill = "Blah")
table(uk_super_q.Easy.to.use)
uk_super_q$NPS <- as.factor(uk_super_q$NPS)
ggplot(uk_super_q, aes(x = NPS)) +
geom_bar() +
xlab("NPS") +
ylab("Total Count")
table(uk_super_q.NPS)
Applying logical statements to a data.frame returns a matrix of TRUE/FALSE values, which are coded in R as 1 and 0, respectively. This allows you to count the number of TRUE values in each column with sum, or more efficiently, with colSums.
colSums(uk_super_q <= 6)
colSums(uk_super_q >= 7 & uk_super_q <= 8)
colSums(uk_super_q >= 9)

Error in layout_base using facet_wrap

I try to facet_wrap my picture by 2 by 2. There is this error when I try to change facet_grid to facet_wrap:
Error in layout_base(data, vars, drop = drop) :
At least one layer must contain all variables used for facetting
I also have not been able to put the linear equation in there. Would you please help? My data is wt2, x-axis is IR and y-axis is GLSEA and I plot it by SEASON.
m_eqn <- function(wt2) {
m = lm(IR ~ GLSEA, wt2);
eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2,
list(a = format(coef(m)[1], digits = 2),
b = format(coef(m)[2], digits = 2),
r2 = format(summary(m)$r.squared, digits = 3)))
as.character(as.expression(eq));
}
p <- ggplot(wt2, aes(x = IR, y = GLSEA, colour = SEASON)) +
geom_point(shape = 1) +
xlab("Water temperature ºC (IR measurement)") +
ylab("Water Temperature ºC (GLSEA)") +
ylim(-10,25) +
xlim(-10,25) +
scale_colour_hue(l=50) +
geom_smooth(method=lm, se=FALSE, fullrange=TRUE) +
theme(strip.text.x = element_text(size=12, face ="bold")) +
facet_wrap(. ~ SEASON) +
coord_fixed() +
geom_abline(intercept = 0,slope =1,linetype="dashed")

Random Forest in R (multi-label-classification)

I'm fairly new to R, trying to implement Random Forest algorithm.
My training and test set have 60 features in the format:
Train: feature1,feature2 .. feature60,Label
Test: FileName,feature1,feature2 ... feature60
Train-sample
mov-mov,or-or,push-push,or-mov,sub-sub,mov-or,sub-mov,xor-or,call-sub,mul-imul,mov-push,push-mov,push-call,or-jz,mov-mul,cmp-or,mov-sub,sub-or,or-sub,or-push,jnz-or,jmp-sub,or-in,mov-call,retn-sub,mul-mul,or-jmp,imul-mul,pop-pop,nop-nop,nop-mul,sub-push,imul-mov,test-or,mul-mov,lea-push,std-mov,in-call,or-call,mov-std,mov-cmp,std-mul,call-or,jz-mov,push-or,pop-retn,add-mov,mov-add,mov-xor,in-inc,mov-pop,in-or,in-push,push-lea,lea-mov,mov-lea,sub-add,std-std,sub-cmp,or-cmp,Label
687,1346,1390,1337,750,2770,1518,418,1523,0,441,532,612,512,0,411,354,310,412,495,134,236,318,237,226,0,0,0,200,0,0,386,39,365,0,0,0,125,528,0,125,0,41,260,169,143,149,61,89,0,127,126,107,44,45,40,79,0,273,157,9
812,873,83,533,88,484,264,106,199,0,188,137,128,51,38,92,131,102,52,58,37,26,428,95,107,0,34,0,58,0,0,39,0,26,0,27,0,152,152,0,45,0,124,0,0,73,84,88,22,23,59,319,105,56,86,47,0,0,43,41,2
Test-sample
FileName,mov-mov,or-or,push-push,or-mov,sub-sub,mov-or,xor-or,sub-mov,call-sub,mul-imul,push-mov,mov-push,push-call,mov-mul,or-jz,cmp-or,mov-sub,sub-or,or-sub,or-push,jmp-sub,jnz-or,or-in,mul-mul,or-jmp,mov-call,retn-sub,imul-mul,nop-mul,pop-pop,nop-nop,imul-mov,sub-push,mul-mov,test-or,lea-push,std-mov,or-call,mov-std,in-call,std-mul,mov-cmp,call-or,push-or,jz-mov,pop-retn,in-or,add-mov,mov-add,in-inc,mov-xor,in-push,push-lea,mov-pop,lea-mov,mov-lea,mov-nop,or-cmp,sub-add,sub-cmp
Ig2DB5tSiEy1cJvV0zdw,166,360,291,194,41,201,62,61,41,18,85,56,121,18,15,0,57,131,113,123,0,9,54,0,0,18,15,0,0,15,0,8,25,0,0,11,0,70,0,43,0,0,63,37,0,14,51,43,56,36,26,0,20,14,17,14,0,9,18,0
k4HCwy5WRFXczJU6eQdT,3,88,106,23,104,0,12,43,59,0,65,87,99,0,2,2,47,22,4,53,1,5,0,0,0,0,46,0,0,0,0,0,4,0,0,6,0,44,0,21,0,0,0,0,0,0,0,2,1,1,3,0,1,2,9,2,0,0,44,2
So what I have so far in R is this,
library(randomForest);
dat <- read.csv("train-sample.csv", sep=",", h=T);
test <- read.csv("test-sample.csv", sep=",", h=T);
attach(dat);
#If I do this, I get Error: unexpected 'in' ...
rfmodel = randomForest (Label ~ mov-mov + or-or + push-push + or-mov + sub-sub + mov-or + sub-mov + xor-or + call-sub + mul-imul + mov-push + push-mov + push-call + or-jz + mov-mul + cmp-or + mov-sub + sub-or + or-sub + or-push + jnz-or + jmp-sub + or-in + mov-call + retn-sub + mul-mul + or-jmp + imul-mul + pop-pop + nop-nop + nop-mul + sub-push + imul-mov + test-or + mul-mov + lea-push + std-mov + in-call + or-call + mov-std + mov-cmp + std-mul + call-or + jz-mov + push-or + pop-retn + add-mov + mov-add + mov-xor + in-inc + mov-pop + in-or + in-push + push-lea + lea-mov + mov-lea + sub-add + std-std + sub-cmp + or-cmp, data=dat);
#If I do this, I get Error in terms.formula(formula, data = data) : invalid model formula in ExtractVars
rfmodel = randomForest (Label ~ 'mov-mov' + 'or-or' + 'push-push' + or-mov + sub-sub + mov-or + sub-mov + xor-or + call-sub + mul-imul + mov-push + push-mov + push-call + or-jz + mov-mul + cmp-or + mov-sub + sub-or + or-sub + or-push + jnz-or + jmp-sub + 'or-in' + mov-call + retn-sub + mul-mul + or-jmp + imul-mul + pop-pop + nop-nop + nop-mul + sub-push + imul-mov + test-or + mul-mov + lea-push + 'std-mov' + 'in-call' + 'or-call' + 'mov-std' + 'mov-cmp' + 'std-mul' + 'call-or' + 'jz-mov' + 'push-or' + 'pop-retn' + 'add-mov' + 'mov-add' + 'mov-xor' + 'in-inc' + 'mov-pop' + 'in-or' + 'in-push' + 'push-lea' + 'lea-mov' + 'mov-lea' + 'sub-add' + 'std-std' + 'sub-cmp' + 'or-cmp', data=dat);
#I even tried this and got Error in na.fail.default(list(Label = c(9L, 2L, 9L, 1L, 8L, 6L, 2L, 2L, : missing values in object
rfmodel <- randomForest(Label~., dat);
So I'm kinda stuck. I want to end up using something like,
predicted <- predict(rfmodel, test, type="response");
prop.table(table(test$FileName, predicted),1);
To get an output in form of:
FileName, Label1, Label2, Label3 .. Label9
name1, 0.98, 0, 0.02, 0, 0 .. 0
(basically the fileName with probabilities of each label)
Any help is appreciated. Thank you.

How to convert R formula to text?

I have trouble working with formula as with text. What I'm trying to do is to concatenate the formula to the title of the graph. However, when I try to work with the formula as with text, I fail:
model <- lm(celkem ~ rok + mesic)
formula(model)
# celkem ~ rok + mesic
This is fine. Now I want to build string like "my text celkem ~ rok + mesic" - this is where the problem comes:
paste("my text", formula(model))
# [1] "my text ~" "my text celkem" "my text rok + mesic"
paste("my text", as.character(formula(model)))
# [1] "my text ~" "my text celkem" "my text rok + mesic"
paste("my text", toString(formula(model)))
# [1] "my text ~, celkem, rok + mesic"
Now I see there is a sprint function in package gtools, but I think this is such a basic thing that it deserves a solution within the default environment!!
A short solution from the package formula.tools, as a function as.character.formula:
frm <- celkem ~ rok + mesic
Reduce(paste, deparse(frm))
# [1] "celkem ~ rok + mesic"
library(formula.tools)
as.character(frm)
# [1] "celkem ~ rok + mesic"
Reduce might be useful in case of long formulas:
frm <- formula(paste("y ~ ", paste0("x", 1:12, collapse = " + ")))
deparse(frm)
# [1] "y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + "
# [2] " x12"
Reduce(paste, deparse(frm))
# [1] "y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12"
Which is because of width.cutoff = 60L in ?deparse.
Try format :
paste("my text", format(frm))
## [1] "my text celkem ~ rok + mesic"
Simplest solution covering everything:
f <- formula(model)
paste(deparse(f, width.cutoff = 500), collapse="")
R 4.0.0 (released 2020-04-24) introduced deparse1 which never splits the result into multiple strings:
f <- y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o +
p + q + r + s + t + u + v + w + x + y + z
deparse(f)
# [1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + " " p + q + r + s + t + u + v + w + x + y + z"
deparse1(f)
# [1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z"
However, it still has a width.cutoff argument (default (an maximum): 500) after which linebreaks are introduced but with lines separated by collapse (default: " ") not \n, leaving extra white whitespace (even with collapse = "") (use gsub to remove them if needed, see Ross D's answer):
> f <- rlang::parse_expr( paste0("y~", paste0(rep(letters, 20), collapse="+")))
> deparse1(f, collapse = "")
[1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z"
To use it in R < 4.0.0 use backports (recommended)
or copy it's implementation:
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2019 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
deparse1 <- function (expr, collapse = " ", width.cutoff = 500L, ...)
paste(deparse(expr, width.cutoff, ...), collapse = collapse)
or as an alternative to Julius's version (note: your code was not self-contained)
celkem = 1
rok = 1
mesic = 1
model <- lm(celkem ~ rok + mesic)
paste("my model ", deparse(formula(model)))
The easiest way is this:
f = formula(model)
paste(f[2],f[3],sep='~')
done!
Here a solution which use print.formula, it seems trick but it do the job in oneline and avoid the use of deparse and no need to use extra package. I just capture the output of the print formula, using capture.output
paste("my text",capture.output(print(formula(celkem ~ rok + mesic))))
[1] "my text celkem ~ rok + mesic"
In case of long formula:
ff <- formula(paste("y ~ ", paste0("x", 1:12, collapse = " + ")))
paste("my text",paste(capture.output(print(ff)), collapse= ' '))
"my text y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12"
Another deparse-based solution is rlang::expr_text() (and rlang::quo_text()):
f <- Y ~ 1 + a + b + c + d + e + f + g + h + i +j + k + l + m + n + o + p + q + r + s + t + u
rlang::quo_text(f)
#> [1] "Y ~ 1 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + \n o + p + q + r + s + t + u"
They do have a width argument to avoid line breaks, but that is limited to 500 characters too. At least it's a single function that is most likely loaded already...
Then add gsub to remove white spaces
gsub(" ", "", paste(format(frm), collapse = ""))
Was optimizing some functions today. A few approaches that have not been mentioned so far.
f <- Y ~ 1 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u
bench::mark(
expression = as.character(as.expression(f)),
deparse = deparse(f, width.cutoff = 500L),
deparse1 = deparse1(f),
tools = formula.tools:::as.character.formula(f),
stringi = stringi::stri_c(f),
I = as.character(I(f)),
as = as(f, "character"),
txt = gettext(f),
txtf = gettextf(f),
sub = sub("", "", f),
chr = as.character(f),
str = substring(f, 1L),
paste = paste0(f),
)[c(1, 3, 5, 7)]
#> # A tibble: 13 x 3
#> expression median mem_alloc
#> <bch:expr> <bch:tm> <bch:byt>
#> 1 expression 15.4us 0B
#> 2 deparse 31us 0B
#> 3 deparse1 34us 0B
#> 4 tools 58.7us 1.74MB
#> 5 stringi 67us 3.09KB
#> 6 I 64.1us 0B
#> 7 as 100.5us 521.61KB
#> 8 txt 83.4us 0B
#> 9 txtf 85.8us 3.12KB
#> 10 sub 64.6us 0B
#> 11 chr 60us 0B
#> 12 str 62.8us 0B
#> 13 paste 63.5us 0B

Resources