Как подсчитать вхождения «c(» в строке во фрейме данных в R?

#r #string #count

Вопрос:

У меня есть фрейм данных, в котором определенные столбцы содержат сообщения об ошибках и предупреждения от Mplus. Текст сохраняется в странном формате, поэтому вместо того, чтобы пытаться обрабатывать каждое сообщение, я надеялся просто подсчитать количество сообщений, подсчитав вхождения c( в ячейке, поскольку это уникальная комбинация символов, которая появляется перед каждым предупреждением или ошибкой.

Например, одна ячейка содержит сообщения:

 [[1]]
[1] "c("All variables are uncorrelated with all other variables within class.""
[2] " "Check that this is what is intended.""                                  
[3] " "1 WARNING(S) FOUND IN THE INPUT INSTRUCTIONS")"                         
[4] " c("WARNING:  THE BEST LOGLIKELIHOOD VALUE WAS NOT REPLICATED.  THE""     
[5] " "SOLUTION MAY NOT BE TRUSTWORTHY DUE TO LOCAL MAXIMA.  INCREASE THE""    
[6] " "NUMBER OF RANDOM STARTS.")" 
 

в то время как другой содержит более короткое сообщение, подобное этому:

 [[1]]
[1] "c("All variables are uncorrelated with all other variables within class.""
[2] " "Check that this is what is intended.""                                  
[3] " "1 WARNING(S) FOUND IN THE INPUT INSTRUCTIONS")" 
 

Я пробовал использовать str_count несколькими различными способами, включая мою последнюю попытку:

     str_count(test#, '//c(//')
 

но я получаю ошибку: Error: '/' is an unrecognized escape in character string starting "'//c(/" . В идеале это вернет 2 для первого примера и 1 для второго примера.

Как я могу подсчитать вхождения этой уникальной строки, когда она содержит символы, которые отбрасывают большинство способов ее инкапсуляции или экранирования?

Вот несколько простых в использовании тестовых кодов, чтобы примерить их!

 test1 <- '"c("All variables are uncorrelated with all other variables within class."" " "Check that this is what is intended."" " "1 WARNING(S) FOUND IN THE INPUT INSTRUCTIONS")"'

test2 <- '"c("All variables are uncorrelated with all other variables within class."" " "Check that this is what is intended."" " "1 WARNING(S) FOUND IN THE INPUT INSTRUCTIONS")" " c("WARNING:  THE BEST LOGLIKELIHOOD VALUE WAS NOT REPLICATED.  THE"" " "SOLUTION MAY NOT BE TRUSTWORTHY DUE TO LOCAL MAXIMA.  INCREASE THE"" " "NUMBER OF RANDOM STARTS.")"'

 

Комментарии:

1. Это не решение вашей проблемы, но вы подумывали о том, чтобы использовать lavaan для выполнения SEM непосредственно в R?

2. мне кажется, что может быть проще свести проблему к тому, чтобы просто найти c( , что вы можете сделать это вот так: str_count(test1, "c\(")

3. Это выглядит так, как будто data.frame был построен плохо; было бы лучше сохранить исходный формат «список векторов символов» (или это сложнее?) и использовать, например lengths() , в соответствии df = data.frame(x = 1:2); df$y = list(c("a", "b"), "d"); lengths(df$y) с .

4. Мы посмотрели на лаваана, но что-то в оценках или вариантах ввода в целом заставило моего советника решить, что Mplus был лучшим вариантом, так что на данный момент это не в моей власти. @deschen

5. @D. J Это действительно могло бы сработать очень хорошо, я думаю, я не до конца понимал, как полностью работали варианты побега — (и оба доставляли мне кучу проблем.

Ответ №1:

Вы можете попробовать либо уменьшить часть, подлежащую учету, как в моем комментарии

 str_count(test1, "c\(")
 

или вы можете удлинить параметр и использовать аргумент fixed (), проверив наличие c(" :

 str_count(test1, fixed('c("'))
 

как вы можете видеть, оба способа показывают правильный ответ(ы):

 string1 <- 'c("All variables are uncorrelated with all other variables within class."" 
             " "Check that this is what is intended."" 
             " "1 WARNING(S) FOUND IN THE INPUT INSTRUCTIONS")" 
             " c("WARNING:  THE BEST LOGLIKELIHOOD VALUE WAS NOT REPLICATED. 
             THE"" " "SOLUTION MAY NOT BE TRUSTWORTHY DUE TO LOCAL MAXIMA.  INCREASE THE""
             " "NUMBER OF RANDOM STARTS.")'

> str_count(string1, fixed('c("'))
[1] 2
> str_count(string1, "c\(")
[1] 2
 

Ответ №2:

Ты мог бы попробовать gregexpr() .

 test1 <- '"c(" foo bar baz'
test2 <- '"c(" foo bar baz "c(" baz bar foo'

length(unlist(gregexpr('c\(', test1)))
# [1] 1
length(unlist(gregexpr('c\(', test2)))
# [1] 2
length(unlist(gregexpr('c\(', list(test1, test2))))
# [1] 3