This question already has an answer here:
I am trying to write a function that finds pattern in names, with the help of stringr
package.
My function looks like following:
namezz=function(thepatternx,data=data,column=Name){
library(stringr)
thepattern=as.character(quote(thepatternx))
pattern <- thepattern
strings <- data$column ##data$column is a character vector
found=str_detect(strings, pattern)
yez= rownames(data[which(found==TRUE),])
hhh=as.numeric(yez)+1
return(hhh)
}
When I call the function I get an error:
namezz(Primus)
Error in namezz(Primus) :
promise already under evaluation: recursive default argument reference or earlier problems?
Can't understand the error, and what I am doing wrong.. Thanks in advance for any guidelines:)
EDIT
: If I instead write it like this:
namezz=function(thepatternx,data,Name){
library(stringr)
thepattern=as.character(quote(thepatternx))
pattern <- thepattern
strings <- data$Name #####data$column is a character vector
found=str_detect(strings, pattern)
yez= rownames(data[which(found==TRUE),])
hhh=as.numeric(yez)+1
return(hhh)
}
I get:
namezz(Primus,data,Name)
numeric(0)
Which is not correct, because if I do the procedure without putting it in a function I get the rows:
pattern="Primus"
strings <- data$Name
mja=str_detect(strings, pattern)
yez= rownames(data[which(mja==TRUE),])
hhh=as.numeric(yez)+1
[1] 2 3 4 5 6 7 8 9
Here is a dput:
dput(head(data))
structure(list(Year = 1901:1906, Name = c(">>Primus<< sbk", ">>Primus<< sbk",
">>Primus<< sbk", ">>Primus<< sbk", ">>Primus<< sbk", ">>Primus<< sbk"
), Established = c(1899L, 1899L, 1899L, 1899L, 1899L, 1899L),
Bolagskod = c(2L, 2L, 2L, 2L, 2L, 2L), Kategori = c(2L, 0L,
0L, 0L, 0L, 0L), BranschTillhörighet = c(2L, 2L, 2L, 2L,
2L, 2L), Startår = c(1901L, 1901L, 1901L, 1901L, 1901L, 1901L
), Stoppår = c(1908L, 1908L, 1908L, 1908L, 1908L, 1908L),
Ranges = c("8 1901 - 1908 >>Primus<< sbk", "8 1901 - 1908 >>Primus<< sbk",
"8 1901 - 1908 >>Primus<< sbk", "8 1901 - 1908 >>Primus<< sbk",
"8 1901 - 1908 >>Primus<< sbk", "8 1901 - 1908 >>Primus<< sbk"
), Years.present = c("1901 1902 1903 1904 1905 1906 1907 1908",
"1901 1902 1903 1904 1905 1906 1907 1908", "1901 1902 1903 1904 1905 1906 1907 1908",
"1901 1902 1903 1904 1905 1906 1907 1908", "1901 1902 1903 1904 1905 1906 1907 1908",
"1901 1902 1903 1904 1905 1906 1907 1908"), Delägare.män. = c(267L,
271L, 317L, 339L, 339L, 345L), Delägare.kvinnor. = c(246L,
251L, 236L, 244L, 260L, NA), Sjukdomsfall.män. = c(66L, 61L,
100L, 103L, 106L, 82L), Sjukdomsfall.kvinnor. = c(59L, 55L,
60L, 71L, 85L, 60L), Sjukdagar.män. = c(1686L, 1918L, 2149L,
2212L, 2331L, 1890L), Sjukdagar.kvinnor. = c(1681L, 1197L,
1589L, 1904L, 2282L, 1750L), Inkomster.InträdesAvgifter. = c(303L,
NA, NA, NA, NA, NA), Inkomster.RegelbundnaAvgifter. = c(4901L,
4939L, 5172L, 5687L, 5728L, 5879L), Inkomster.UtdebiteradeAvgifter. = c(1313L,
1045L, 1141L, 2024L, 1462L, 1934L), Inkomster.Böter. = c(241L,
NA, NA, NA, NA, NA), SummaMedl.avg. = c(6758L, 5984L, 6313L,
7711L, 7190L, 7813L), Inkomster.BidragStatKommun. = c(366L,
440L, 456L, 464L, 476L, 493L), Inkomster.Räntor. = c(NA_integer_,
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_
), Inkomster.Övrigt. = c(24L, 722L, 874L, 605L, 805L, 647L
), Inkomster.Summa. = c(7148L, 7146L, 7644L, 8781L, 8472L,
8954L), DiffIntäkter.SummaMotVerkligSumma. = c(0L, 0L, -1L,
-1L, -1L, -1L), Utgifter.Sjukhjälp. = c(4735L, 4450L, 5300L,
5870L, 6560L, 5200L), Utgifter.Begravningshjälp. = c(1200L,
795L, 1045L, 1810L, 955L, 1675L), Utgifter.Arvoden. = c(NA_integer_,
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_
), Utgifter.Förvaltning. = c(956L, 972L, 1038L, 1156L, 1523L,
1171L), Utgifter.Övrigt. = c(25L, NA, 20L, 5L, NA, NA), Utgifter.Behållning. = c(231,
929, 240, -59, -565, 908), Utgifter.SummaÖvrigt.Behållning. = c(256L,
929L, 260L, -54L, -565L, 908L), Utgifter.Summa. = c(7148L,
6217L, 7403L, 8841L, 9038L, 8046L), KOLL = c(-1L, 0L, 0L,
0L, 0L, 0L), Tillgångar.KontantIKassa. = c(835L, 1765L, 2006L,
1946L, 1380L, 2259L), Tillgångar.KontantMedelBank. = c(NA_integer_,
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_
), Tillgångar.Totalt. = c(836L, 1765L, 2006L, 1946L, 1468L,
2348L), Skulder.Totalt. = c(NA_integer_, NA_integer_, NA_integer_,
NA_integer_, NA_integer_, NA_integer_), TillgångarÖverSkulder = c(NA_integer_,
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_
)), .Names = c("Year", "Name", "Established", "Bolagskod",
"Kategori", "BranschTillhörighet", "Startår", "Stoppår", "Ranges",
"Years.present", "Delägare.män.", "Delägare.kvinnor.", "Sjukdomsfall.män.",
"Sjukdomsfall.kvinnor.", "Sjukdagar.män.", "Sjukdagar.kvinnor.",
"Inkomster.InträdesAvgifter.", "Inkomster.RegelbundnaAvgifter.",
"Inkomster.UtdebiteradeAvgifter.", "Inkomster.Böter.", "SummaMedl.avg.",
"Inkomster.BidragStatKommun.", "Inkomster.Räntor.", "Inkomster.Övrigt.",
"Inkomster.Summa.", "DiffIntäkter.SummaMotVerkligSumma.", "Utgifter.Sjukhjälp.",
"Utgifter.Begravningshjälp.", "Utgifter.Arvoden.", "Utgifter.Förvaltning.",
"Utgifter.Övrigt.", "Utgifter.Behållning.", "Utgifter.SummaÖvrigt.Behållning.",
"Utgifter.Summa.", "KOLL", "Tillgångar.KontantIKassa.", "Tillgångar.KontantMedelBank.",
"Tillgångar.Totalt.", "Skulder.Totalt.", "TillgångarÖverSkulder"
), row.names = c(NA, 6L), class = "data.frame")
Edit
This works:
namezz=function(thepatternx,data,Name){
library(stringr)
thepattern=thepatternx
pattern <- thepattern
strings <- data$Name
mja=str_detect(strings, pattern)
yez= rownames(data[which(mja==TRUE),])
hhh=as.numeric(yez)+1
return(hhh)
}
namezz("Primus",data,Name)
[1] 2 3 4 5 6 7 8 9
But how can i pass Primus without the quotation marks, namezz(Primus,data,Name)
?. Thinking about something as in my question, but as.character(quote())
does not work..
Someone can correct me on this, but I think that you are passing Primus and Name as objects to the function and it is looking in the .GlobalEnv for those objects and is not finding them, therefore your function is failing to carry out most of your instructions (and is returning nothing). I have edited your function a bit.
Instead try this...
namezz <- function( pattern = " ", data , column= "Name" ){
library(stringr)
strings <- data[ , column ] ##data$column is a character vector
found = str_detect( strings , pattern )
yez = rownames( data[ which( found==TRUE ) , ] )
hhh = as.numeric( yez ) + 1
return( hhh )
}
Then you must use the function like so:
namezz( "Primus" , data = data ) #In this case the default for column is "Name" as you want
The problem with passing data = data is explained very nicely here. An excerpt from that post (where they refer to testparams you would refer to data)...
"One of the most important things to know about the evaluation of arguments to a function is that supplied arguments and default arguments are treated differently. The supplied arguments to a function are evaluated in the evaluation frame of the calling function. The default arguments to a function are evaluated in the evaluation frame of the function."
the parameter testparams, when no matching argument is passed, is given the default value which is the value of the variable testparams looked-up not in the environment where foo is defined, and not in the environment where foo is called, but rather in the local environment created when the function is called and where parameters are mapped to values -- and in this environment, testparams is a parameter, which is already being under evaluation, hence the recursive lookup error.
来源:https://stackoverflow.com/questions/14982223/an-error-i-cant-understand-promise-already-under-evaluation