Vectorize over all combinations of arguments - r

Is there a way to vectorize an R function over all combinations of multiple parameters and return the result as a list?
As an example, using Vectorize over rnorm produces the following, but I would like to have a list of vectors corresponding to each combination of the arguments (so it should return a list of 60 vectors instead of just 5):
> vrnorm <- Vectorize(rnorm)
> vrnorm( 10*1:5, mean = 1:4, sd = 1:3)
[[1]]
[1] 1.37858918 -0.85432372 1.87321175 2.08362291 0.02950438 1.67967249
[7] 2.25954748 1.44031251 0.09816078 0.91365201
[[2]]
[1] 1.7717267 1.7961157 2.3291686 2.6114272 2.6228930 -0.2580403
[7] 3.3232109 -0.4652434 -0.4803258 -0.1170871 0.1158350 -1.0902252
[13] -0.6400934 3.6625290 2.5924096 4.5878564 0.7265718 3.2034281
[19] -0.2499768 2.0164275
[[3]]
[1] 5.8251252 3.1089121 2.8893594 2.9079357 1.9308677 4.3359878
[7] -0.3668157 4.9728508 -0.6494110 6.7729562 6.1623976 -0.1696638
[13] 5.4664038 3.8141798 -3.1842879 2.3985010 0.3840465 4.0696628
[19] 4.8217798 3.3135100 4.9028273 3.6193840 4.8861864 3.9871897
[25] -0.1059491 3.8961742 4.8293925 3.8935335 6.3194862 4.7846143
[[4]]
[1] 3.737043 2.849215 4.611868 3.494396 2.909659 4.861474 2.000194 3.343171
[9] 4.019523 3.277575 3.885272 3.331160 4.581551 4.960162 3.061960 5.359514
[17] 4.651848 3.640535 3.612368 4.338019 5.233665 3.585976 4.018191 4.320883
[25] 2.598541 3.519587 5.231375 4.733647 2.493334 2.791483 4.330052 2.498424
[33] 3.317115 3.515012 5.079780 4.720884 3.055191 5.262385 1.939961 4.779480
[[5]]
[1] 4.31697756 0.93754587 3.96698522 -0.03680018 1.94987430 1.73985617
[7] -1.42300550 2.07764933 0.45701395 2.42548257 0.67745524 -2.42054060
[13] 1.14655845 1.60277193 -1.04636658 0.94097335 3.07688803 0.58049012
[19] 1.25812532 1.91613097 -2.95408979 3.00990345 -0.67314868 0.64746260
[25] 1.69640497 0.68493689 2.84261574 1.65290227 4.16990548 -3.30426803
[31] 3.80508273 5.95888355 -0.09021591 3.88157980 -1.19166351 2.70208228
[37] -0.56278834 -0.83943824 -0.86868493 -1.19995506 -2.30275483 1.70435276
[43] 2.67984044 -0.04976799 0.98716782 2.71171575 5.21648742 0.13860495
[49] 1.61038570 0.50679460

Use expand.grid to expand all arguments and create a data frame, and then use mapply.
dat <- expand.grid(n = 10 * 1:5, mean = 1:4, sd = 1:3)
mapply(rnorm, dat$n, dat$mean, dat$sd, SIMPLIFY = FALSE)

You can also use purrr::pmap() as an alternative to mapply
library(purrr)
dat <- expand.grid(n = 10 * 1:5, mean = 1:4, sd = 1:3)
pmap(dat, rnorm)

Related

Is there a specific function in R to merge 2 vectors [duplicate]

This question already has answers here:
Pasting two vectors with combinations of all vectors' elements
(8 answers)
Closed 2 years ago.
I have two vectors, one that contains a list of variables, and one that contains dates, such as
Variables_Pays <- c("PIB", "ConsommationPrivee","ConsommationPubliques",
"FBCF","ProductionIndustrielle","Inflation","InflationSousJacente",
"PrixProductionIndustrielle","CoutHoraireTravail")
Annee_Pays <- c("2000","2001")
I want to merge them to have a vector with each variable indexed by my date, that is my desired output is
> Colonnes_Pays_Principaux
[1] "PIB_2020" "PIB_2021" "ConsommationPrivee_2020"
[4] "ConsommationPrivee_2021" "ConsommationPubliques_2020" "ConsommationPubliques_2021"
[7] "FBCF_2020" "FBCF_2021" "ProductionIndustrielle_2020"
[10] "ProductionIndustrielle_2021" "Inflation_2020" "Inflation_2021"
[13] "InflationSousJacente_2020" "InflationSousJacente_2021" "PrixProductionIndustrielle_2020"
[16] "PrixProductionIndustrielle_2021" "CoutHoraireTravail_2020" "CoutHoraireTravail_2021"
Is there a simpler / more readabl way than a double for loop as I have tried and succeeded below ?
Colonnes_Pays_Principaux <- vector()
for (Variable in (1:length(Variables_Pays))){
for (Annee in (1:length(Annee_Pays))){
Colonnes_Pays_Principaux=
append(Colonnes_Pays_Principaux,
paste(Variables_Pays[Variable],Annee_Pays[Annee],sep="_")
)
}
}
expand.grid will create a data frame with all combinations of the two vectors.
with(
expand.grid(Variables_Pays, Annee_Pays),
paste0(Var1, "_", Var2)
)
#> [1] "PIB_2000" "ConsommationPrivee_2000"
#> [3] "ConsommationPubliques_2000" "FBCF_2000"
#> [5] "ProductionIndustrielle_2000" "Inflation_2000"
#> [7] "InflationSousJacente_2000" "PrixProductionIndustrielle_2000"
#> [9] "CoutHoraireTravail_2000" "PIB_2001"
#> [11] "ConsommationPrivee_2001" "ConsommationPubliques_2001"
#> [13] "FBCF_2001" "ProductionIndustrielle_2001"
#> [15] "Inflation_2001" "InflationSousJacente_2001"
#> [17] "PrixProductionIndustrielle_2001" "CoutHoraireTravail_2001"
We can use outer :
c(t(outer(Variables_Pays, Annee_Pays, paste, sep = '_')))
# [1] "PIB_2000" "PIB_2001"
# [3] "ConsommationPrivee_2000" "ConsommationPrivee_2001"
# [5] "ConsommationPubliques_2000" "ConsommationPubliques_2001"
# [7] "FBCF_2000" "FBCF_2001"
# [9] "ProductionIndustrielle_2000" "ProductionIndustrielle_2001"
#[11] "Inflation_2000" "Inflation_2001"
#[13] "InflationSousJacente_2000" "InflationSousJacente_2001"
#[15] "PrixProductionIndustrielle_2000" "PrixProductionIndustrielle_2001"
#[17] "CoutHoraireTravail_2000" "CoutHoraireTravail_2001"
No real need to go beyond the basics here! Use paste for pasting the strings and rep to repeat either Annee_Pays och Variables_Pays to get all combinations:
Variables_Pays <- c("PIB", "ConsommationPrivee","ConsommationPubliques",
"FBCF","ProductionIndustrielle","Inflation","InflationSousJacente",
"PrixProductionIndustrielle","CoutHoraireTravail")
Annee_Pays <- c("2000","2001")
# To get this is the same order as in your example:
paste(rep(Variables_Pays, rep(2, length(Variables_Pays))), Annee_Pays, sep = "_")
# Alternative order:
paste(Variables_Pays, rep(Annee_Pays, rep(length(Variables_Pays), 2)), sep = "_")
# Or, if order doesn't matter too much:
paste(Variables_Pays, rep(Annee_Pays, length(Variables_Pays)), sep = "_")
In base R:
Variables_Pays <- c("PIB", "ConsommationPrivee","ConsommationPubliques",
"FBCF","ProductionIndustrielle","Inflation","InflationSousJacente",
"PrixProductionIndustrielle","CoutHoraireTravail")
Annee_Pays <- c("2000","2001")
cbind(paste(Variables_Pays, Annee_Pays,sep="_"),paste(Variables_Pays, rev(Annee_Pays),sep="_")

Split a sequence of numbers into groups of 10 digits using R

I would like for R to read in the first 10,000 digits of Pi and group every 10 digits together
e.g., I want R to read in a sequence
pi <- 3.14159265358979323846264338327950288419716939937510582097...
and would like R to give me a table where each row contains 10 digit:
3141592653
5897932384
6264338327
...
I am new to R and really don't know where to start so any help would be much appreciated!
Thank you in advance
https://rextester.com/OQRM27791
p <- strsplit("314159265358979323846264338327950288419716939937510582097", "")
digits <- p[[1]]
split(digits, ceiling((1:length(digits)) / 10));
Here's one way to do it. It's fully reproducible, so just cut and paste it into your R console. The vector result is the first 10,000 digits of pi, split into 1000 strings of 10 digits.
For this many digits, I have used an online source for the precalculated value of pi. This is read in using readChar and the decimal point is stripped out with gsub. The resulting string is split into individual characters and put in a 1000 * 10 matrix (filled row-wise). The rows are then pasted into strings, giving the result. I have displayed only the first 100 entries of result for clarity of presentation.
pi_url <- "https://www.pi2e.ch/blog/wp-content/uploads/2017/03/pi_dec_1m.txt"
pi_char <- gsub("\\.", "", readChar(url, 1e4 + 1))
pi_mat <- matrix(strsplit(pi_char, "")[[1]], byrow = TRUE, ncol = 10)
result <- apply(pi_mat, 1, paste0, collapse = "")
head(result, 100)
#> [1] "3141592653" "5897932384" "6264338327" "9502884197" "1693993751"
#> [6] "0582097494" "4592307816" "4062862089" "9862803482" "5342117067"
#> [11] "9821480865" "1328230664" "7093844609" "5505822317" "2535940812"
#> [16] "8481117450" "2841027019" "3852110555" "9644622948" "9549303819"
#> [21] "6442881097" "5665933446" "1284756482" "3378678316" "5271201909"
#> [26] "1456485669" "2346034861" "0454326648" "2133936072" "6024914127"
#> [31] "3724587006" "6063155881" "7488152092" "0962829254" "0917153643"
#> [36] "6789259036" "0011330530" "5488204665" "2138414695" "1941511609"
#> [41] "4330572703" "6575959195" "3092186117" "3819326117" "9310511854"
#> [46] "8074462379" "9627495673" "5188575272" "4891227938" "1830119491"
#> [51] "2983367336" "2440656643" "0860213949" "4639522473" "7190702179"
#> [56] "8609437027" "7053921717" "6293176752" "3846748184" "6766940513"
#> [61] "2000568127" "1452635608" "2778577134" "2757789609" "1736371787"
#> [66] "2146844090" "1224953430" "1465495853" "7105079227" "9689258923"
#> [71] "5420199561" "1212902196" "0864034418" "1598136297" "7477130996"
#> [76] "0518707211" "3499999983" "7297804995" "1059731732" "8160963185"
#> [81] "9502445945" "5346908302" "6425223082" "5334468503" "5261931188"
#> [86] "1710100031" "3783875288" "6587533208" "3814206171" "7766914730"
#> [91] "3598253490" "4287554687" "3115956286" "3882353787" "5937519577"
#> [96] "8185778053" "2171226806" "6130019278" "7661119590" "9216420198"
Created on 2020-07-23 by the reprex package (v0.3.0)
We can use str_extract:
pi <- readLines("https://www.pi2e.ch/blog/wp-content/uploads/2017/03/pi_dec_1m.txt")
library(stringr)
t <- unlist(str_extract_all(sub("\\.","", pi), "\\d{10}"))
t[1:100]
[1] "3141592653" "5897932384" "6264338327" "9502884197" "1693993751" "0582097494" "4592307816" "4062862089"
[9] "9862803482" "5342117067" "9821480865" "1328230664" "7093844609" "5505822317" "2535940812" "8481117450"
[17] "2841027019" "3852110555" "9644622948" "9549303819" "6442881097" "5665933446" "1284756482" "3378678316"
[25] "5271201909" "1456485669" "2346034861" "0454326648" "2133936072" "6024914127" "3724587006" "6063155881"
[33] "7488152092" "0962829254" "0917153643" "6789259036" "0011330530" "5488204665" "2138414695" "1941511609"
[41] "4330572703" "6575959195" "3092186117" "3819326117" "9310511854" "8074462379" "9627495673" "5188575272"
[49] "4891227938" "1830119491" "2983367336" "2440656643" "0860213949" "4639522473" "7190702179" "8609437027"
[57] "7053921717" "6293176752" "3846748184" "6766940513" "2000568127" "1452635608" "2778577134" "2757789609"
[65] "1736371787" "2146844090" "1224953430" "1465495853" "7105079227" "9689258923" "5420199561" "1212902196"
[73] "0864034418" "1598136297" "7477130996" "0518707211" "3499999983" "7297804995" "1059731732" "8160963185"
[81] "9502445945" "5346908302" "6425223082" "5334468503" "5261931188" "1710100031" "3783875288" "6587533208"
[89] "3814206171" "7766914730" "3598253490" "4287554687" "3115956286" "3882353787" "5937519577" "8185778053"
[97] "2171226806" "6130019278" "7661119590" "9216420198"

extract list elements and concatenate into a string in r

using the variable list below I want to for all combinations, join the variables into a string seperated by "+"
l_ALLVar_list <- c("a","b","c","d","z1","z2","z3")
I have the code to generate the 127 combinations
all_combos=do.call("c", lapply(seq_along(l_ALLVar_list), function(i) combn(l_ALLVar_list, i, FUN = list)))
and using position 66 as an example
> all_combos[66]
[[1]]
[1] "a" "b" "c" "z2"
I want to be able to join the elements of these at index 66 into the string a+b+c+z2
I have tried
str_c(c(lol[66]),collapse=',')
but it comes back as
c(\"weight\", \"length\", \"wheel_base\", \"city_mpg\")
paste(all_combos[66], collapse = '')
produces the same again
any help would be appreciated
You can use the FUN argument in combn to paste all the combinations of l_ALLVar_list in one call, eliminating the need for your all_combos list.
unlist(lapply(seq_along(l_ALLVar_list), combn, x=l_ALLVar_list, paste, collapse="+"))
# [1] "a" "b" "c" "d" "z1"
# [6] "z2" "z3" "a+b" "a+c" "a+d"
# [11] "a+z1" "a+z2" "a+z3" "b+c" "b+d"
# [16] "b+z1" "b+z2" "b+z3" "c+d" "c+z1"
# [21] "c+z2" "c+z3" "d+z1" "d+z2" "d+z3"
# [26] "z1+z2" "z1+z3" "z2+z3" "a+b+c" "a+b+d"
# [31] "a+b+z1" "a+b+z2" "a+b+z3" "a+c+d" "a+c+z1"
# [36] "a+c+z2" "a+c+z3" "a+d+z1" "a+d+z2" "a+d+z3"
# [41] "a+z1+z2" "a+z1+z3" "a+z2+z3" "b+c+d" "b+c+z1"
# [46] "b+c+z2" "b+c+z3" "b+d+z1" "b+d+z2" "b+d+z3"
# [51] "b+z1+z2" "b+z1+z3" "b+z2+z3" "c+d+z1" "c+d+z2"
# [56] "c+d+z3" "c+z1+z2" "c+z1+z3" "c+z2+z3" "d+z1+z2"
# [61] "d+z1+z3" "d+z2+z3" "z1+z2+z3" "a+b+c+d" "a+b+c+z1"
# [66] "a+b+c+z2" "a+b+c+z3" "a+b+d+z1" "a+b+d+z2" "a+b+d+z3"
# [71] "a+b+z1+z2" "a+b+z1+z3" "a+b+z2+z3" "a+c+d+z1" "a+c+d+z2"
# [76] "a+c+d+z3" "a+c+z1+z2" "a+c+z1+z3" "a+c+z2+z3" "a+d+z1+z2"
# [81] "a+d+z1+z3" "a+d+z2+z3" "a+z1+z2+z3" "b+c+d+z1" "b+c+d+z2"
# [86] "b+c+d+z3" "b+c+z1+z2" "b+c+z1+z3" "b+c+z2+z3" "b+d+z1+z2"
# [91] "b+d+z1+z3" "b+d+z2+z3" "b+z1+z2+z3" "c+d+z1+z2" "c+d+z1+z3"
# [96] "c+d+z2+z3" "c+z1+z2+z3" "d+z1+z2+z3" "a+b+c+d+z1" "a+b+c+d+z2"
#[101] "a+b+c+d+z3" "a+b+c+z1+z2" "a+b+c+z1+z3" "a+b+c+z2+z3" "a+b+d+z1+z2"
#[106] "a+b+d+z1+z3" "a+b+d+z2+z3" "a+b+z1+z2+z3" "a+c+d+z1+z2" "a+c+d+z1+z3"
#[111] "a+c+d+z2+z3" "a+c+z1+z2+z3" "a+d+z1+z2+z3" "b+c+d+z1+z2" "b+c+d+z1+z3"
#[116] "b+c+d+z2+z3" "b+c+z1+z2+z3" "b+d+z1+z2+z3" "c+d+z1+z2+z3" "a+b+c+d+z1+z2"
#[121] "a+b+c+d+z1+z3" "a+b+c+d+z2+z3" "a+b+c+z1+z2+z3" "a+b+d+z1+z2+z3" "a+c+d+z1+z2+z3"
#[126] "b+c+d+z1+z2+z3" "a+b+c+d+z1+z2+z3"
Use lapply to do paste for each item in your list:
result <- unlist(lapply(all_combos,
function(c) do.call(paste, c(as.list(c), sep="+"))))
> result[66:70]
[1] "a+b+c+z2" "a+b+c+z3" "a+b+d+z1" "a+b+d+z2" "a+b+d+z3"

Dividing components of a vector into several data points in R

I am trying to turn a vector of length n (say, 14), and turn it into a vector of length N (say, 90). For example, my vector is
x<-c(5,3,7,11,12,19,40,2,22,6,10,12,12,4)
and I want to turn it into a vector of length 90, by creating 90 equally "spaced" points on this vector- think of x as a function. Is there any way to do that in R?
Something like this?
> x<-c(5,3,7,11,12,19,40,2,22,6,10,12,12,4)
> seq(min(x),max(x),length=90)
[1] 2.000000 2.426966 2.853933 3.280899 3.707865 4.134831 4.561798
[8] 4.988764 5.415730 5.842697 6.269663 6.696629 7.123596 7.550562
[15] 7.977528 8.404494 8.831461 9.258427 9.685393 10.112360 10.539326
[22] 10.966292 11.393258 11.820225 12.247191 12.674157 13.101124 13.528090
[29] 13.955056 14.382022 14.808989 15.235955 15.662921 16.089888 16.516854
[36] 16.943820 17.370787 17.797753 18.224719 18.651685 19.078652 19.505618
[43] 19.932584 20.359551 20.786517 21.213483 21.640449 22.067416 22.494382
[50] 22.921348 23.348315 23.775281 24.202247 24.629213 25.056180 25.483146
[57] 25.910112 26.337079 26.764045 27.191011 27.617978 28.044944 28.471910
[64] 28.898876 29.325843 29.752809 30.179775 30.606742 31.033708 31.460674
[71] 31.887640 32.314607 32.741573 33.168539 33.595506 34.022472 34.449438
[78] 34.876404 35.303371 35.730337 36.157303 36.584270 37.011236 37.438202
[85] 37.865169 38.292135 38.719101 39.146067 39.573034 40.000000
>
Try this:
#data
x <- c(5,3,7,11,12,19,40,2,22,6,10,12,12,4)
#expected new length
N=90
#number of numbers between 2 numbers
my.length.out=round((N-length(x))/(length(x)-1))+1
#new data
x1 <- unlist(
lapply(1:(length(x)-1), function(i)
seq(x[i],x[i+1],length.out = my.length.out)))
#plot
par(mfrow=c(2,1))
plot(x)
plot(x1)

R: gsub, pattern = vector and replacement = vector

As the title states, I am trying to use gsub where I use a vector for the "pattern" and "replacement". Currently, I have a code that looks like this:
names(x1) <- gsub("2110027599", "Inv1", names(x1)) #x1 is a data frame
names(x1) <- gsub("2110025622", "Inv2", names(x1))
names(x1) <- gsub("2110028045", "Inv3", names(x1))
names(x1) <- gsub("2110034716", "Inv4", names(x1))
names(x1) <- gsub("2110069349", "Inv5", names(x1))
names(x1) <- gsub("2110023264", "Inv6", names(x1))
What I hope to do is something like this:
a <- c("2110027599","2110025622","2110028045","2110034716", "2110069349", "2110023264")
b <- c("Inv1","Inv2","Inv3","Inv4","Inv5","Inv6")
names(x1) <- gsub(a,b,names(x1))
I'm guessing there is an apply function somewhere that can do this, but I am not very sure which one to use!
EDIT: names(x1) looks like this (There are many more columns, but I'm leaving them out):
> names(x1)
[1] "2110023264A.Ms.Amp" "2110023264A.Ms.Vol" "2110023264A.Ms.Watt" "2110023264A1.Ms.Amp"
[5] "2110023264A2.Ms.Amp" "2110023264A3.Ms.Amp" "2110023264A4.Ms.Amp" "2110023264A5.Ms.Amp"
[9] "2110023264B.Ms.Amp" "2110023264B.Ms.Vol" "2110023264B.Ms.Watt" "2110023264B1.Ms.Amp"
[13] "2110023264Error" "2110023264E-Total" "2110023264GridMs.Hz" "2110023264GridMs.PhV.phsA"
[17] "2110023264GridMs.PhV.phsB" "2110023264GridMs.PhV.phsC" "2110023264GridMs.TotPFPrc" "2110023264Inv.TmpLimStt"
[21] "2110023264InvCtl.Stt" "2110023264Mode" "2110023264Mt.TotOpTmh" "2110023264Mt.TotTmh"
[25] "2110023264Op.EvtCntUsr" "2110023264Op.EvtNo" "2110023264Op.GriSwStt" "2110023264Op.TmsRmg"
[29] "2110023264Pac" "2110023264PlntCtl.Stt" "2110023264Serial Number" "2110025622A.Ms.Amp"
[33] "2110025622A.Ms.Vol" "2110025622A.Ms.Watt" "2110025622A1.Ms.Amp" "2110025622A2.Ms.Amp"
[37] "2110025622A3.Ms.Amp" "2110025622A4.Ms.Amp" "2110025622A5.Ms.Amp" "2110025622B.Ms.Amp"
[41] "2110025622B.Ms.Vol" "2110025622B.Ms.Watt" "2110025622B1.Ms.Amp" "2110025622Error"
[45] "2110025622E-Total" "2110025622GridMs.Hz" "2110025622GridMs.PhV.phsA" "2110025622GridMs.PhV.phsB"
What I hope to get is this:
> names(x1)
[1] "Inv6A.Ms.Amp" "Inv6A.Ms.Vol" "Inv6A.Ms.Watt" "Inv6A1.Ms.Amp" "Inv6A2.Ms.Amp"
[6] "Inv6A3.Ms.Amp" "Inv6A4.Ms.Amp" "Inv6A5.Ms.Amp" "Inv6B.Ms.Amp" "Inv6B.Ms.Vol"
[11] "Inv6B.Ms.Watt" "Inv6B1.Ms.Amp" "Inv6Error" "Inv6E-Total" "Inv6GridMs.Hz"
[16] "Inv6GridMs.PhV.phsA" "Inv6GridMs.PhV.phsB" "Inv6GridMs.PhV.phsC" "Inv6GridMs.TotPFPrc" "Inv6Inv.TmpLimStt"
[21] "Inv6InvCtl.Stt" "Inv6Mode" "Inv6Mt.TotOpTmh" "Inv6Mt.TotTmh" "Inv6Op.EvtCntUsr"
[26] "Inv6Op.EvtNo" "Inv6Op.GriSwStt" "Inv6Op.TmsRmg" "Inv6Pac" "Inv6PlntCtl.Stt"
[31] "Inv6Serial Number" "Inv2A.Ms.Amp" "Inv2A.Ms.Vol" "Inv2A.Ms.Watt" "Inv2A1.Ms.Amp"
[36] "Inv2A2.Ms.Amp" "Inv2A3.Ms.Amp" "Inv2A4.Ms.Amp" "Inv2A5.Ms.Amp" "Inv2B.Ms.Amp"
[41] "Inv2B.Ms.Vol" "Inv2B.Ms.Watt" "Inv2B1.Ms.Amp" "Inv2Error" "Inv2E-Total"
[46] "Inv2GridMs.Hz" "Inv2GridMs.PhV.phsA" "Inv2GridMs.PhV.phsB"
Lot's of solutions already, here are one more:
The qdap package:
library(qdap)
names(x1) <- mgsub(a,b,names(x1))
From stringr documentation of str_replace_all, "If you want to apply multiple patterns and replacements to the same string, pass a named version to pattern."
Thus using a, b, and names(x1) from above
stringr::str_replace_all(names(x1), setNames(b, a))
EDIT
stringr::str_replace_all calls stringi::stri_replace_all_regex, which can be used directly and is quite a bit quicker.
x <- names(x1)
pattern <- a
replace <- b
microbenchmark::microbenchmark(
str = stringr::str_replace_all(x, setNames(replace, pattern)),
stri = stringi::stri_replace_all_regex(x, pattern, replace, vectorize_all = FALSE)
)
Unit: microseconds
expr min lq mean median uq max neval cld
str 1022.1 1070.45 1286.547 1175.55 1309 2526.8 100 b
stri 145.2 150.45 190.124 160.55 178 457.9 100 a
New Answer
If we can make another assumption, the following should work. The assumption this time is that you are really interested in substituting the first 10 characters from each value in names(x1).
Here, I've stored names(x1) as a character vector named "X1". The solution essentially uses substr to separate the values in X1 into 2 parts, match to figure out the correct replacement option, and paste to put everything back together.
a <- c("2110027599", "2110025622", "2110028045",
"2110034716", "2110069349", "2110023264")
b <- c("Inv1","Inv2","Inv3","Inv4","Inv5","Inv6")
X1pre <- substr(X1, 1, 10)
X1post <- substr(X1, 11, max(nchar(X1)))
paste0(b[match(X1pre, a)], X1post)
# [1] "Inv6A.Ms.Amp" "Inv6A.Ms.Vol" "Inv6A.Ms.Watt"
# [4] "Inv6A1.Ms.Amp" "Inv6A2.Ms.Amp" "Inv6A3.Ms.Amp"
# [7] "Inv6A4.Ms.Amp" "Inv6A5.Ms.Amp" "Inv6B.Ms.Amp"
# [10] "Inv6B.Ms.Vol" "Inv6B.Ms.Watt" "Inv6B1.Ms.Amp"
# [13] "Inv6Error" "Inv6E-Total" "Inv6GridMs.Hz"
# [16] "Inv6GridMs.PhV.phsA" "Inv6GridMs.PhV.phsB" "Inv6GridMs.PhV.phsC"
# [19] "Inv6GridMs.TotPFPrc" "Inv6Inv.TmpLimStt" "Inv6InvCtl.Stt"
# [22] "Inv6Mode" "Inv6Mt.TotOpTmh" "Inv6Mt.TotTmh"
# [25] "Inv6Op.EvtCntUsr" "Inv6Op.EvtNo" "Inv6Op.GriSwStt"
# [28] "Inv6Op.TmsRmg" "Inv6Pac" "Inv6PlntCtl.Stt"
# [31] "Inv6Serial Number" "Inv2A.Ms.Amp" "Inv2A.Ms.Vol"
# [34] "Inv2A.Ms.Watt" "Inv2A1.Ms.Amp" "Inv2A2.Ms.Amp"
# [37] "Inv2A3.Ms.Amp" "Inv2A4.Ms.Amp" "Inv2A5.Ms.Amp"
# [40] "Inv2B.Ms.Amp" "Inv2B.Ms.Vol" "Inv2B.Ms.Watt"
# [43] "Inv2B1.Ms.Amp" "Inv2Error" "Inv2E-Total"
# [46] "Inv2GridMs.Hz" "Inv2GridMs.PhV.phsA" "Inv2GridMs.PhV.phsB"
Old Answer
If we can assume that names(x1) is in the same order as the pattern and replacement and that it is basically a one-for-one replacement, you might be able to get away with just sapply.
Here's an example of that particular situation:
Imagine "names(x)" looks something like this:
X1 <- paste0("A2", a, sequence(length(a)))
X1
# [1] "A221100275991" "A221100256222" "A221100280453"
# [4] "A221100347164" "A221100693495" "A221100232646"
Here's our pattern and replacement vectors:
a <- c("2110027599", "2110025622", "2110028045",
"2110034716", "2110069349", "2110023264")
b <- c("Inv1","Inv2","Inv3","Inv4","Inv5","Inv6")
This is how we might use sapply if these assumptions are valid.
sapply(seq_along(a), function(x) gsub(a[x], b[x], X1[x]))
# [1] "A2Inv11" "A2Inv22" "A2Inv33" "A2Inv44" "A2Inv55" "A2Inv66"
Try mapply.
names(x1) <- mapply(gsub, a, b, names(x1), USE.NAMES = FALSE)
Or, even easier, str_replace from stringr.
library(stringr)
names(x1) <- str_replace(names(x1), a, b)
I needed to do something similar but had to use base R. As long as your vectors are the same length, I think this will work
for (i in seq_along(a)){
names(x1) <- gsub(a[i], b[i], names(x1))
}
Somehow names<- and match seems much more appropriate here...
names( x1 ) <- b[ match( names( x1 ) , a ) ]
But I am making the assumption that the elements of vector a are the actual names of your data.frame.
If a really is a pattern found within each of the names of x1 then this grepl approach with names<- could be useful...
new <- sapply( a , grepl , x = names( x1 ) )
names( x1 ) <- b[ apply( new , 1 , which.max ) ]

Resources