2016-04-25 3 views
2

У меня есть фрейм данных, и я пытаюсь пропустить кадр данных, чтобы идентифицировать те столбцы, которые содержат специальный символ или все заглавные буквы.Схватывающие столбцы со специальными символами и буквами верхнего регистра

Я пробовал несколько вещей, но ничего, где я есть яблоко, чтобы поймать имена столбцов в цикле.

data = data.frame(one=c(1,3,5,1,3,5,1,3,5,1,3,5), two=c(1,3,5,1,3,5,1,3,5,1,3,5), 
       thr=c("A","B","D","E","F","G","H","I","J","H","I","J"), 
       fou=c("A","B","D","A","B","D","A","B","D","A","B","D"), 
       fiv=c(1,3,5,1,3,5,1,3,5,1,3,5), 
       six=c("A","B","D","E","F","G","H","I","J","H","I","J"), 
       sev=c("A","B","D","A","B","D","A","B","D","A","B","D"), 
       eig=c("A","B","D","A","B","D","A","B","D","A","B","D"), 
       nin=c(1.24,3.52,5.33,1.44,3.11,5.33,1.55,3.66,5.33,1.32,3.54,5.77), 
       ten=c(1:12), 
       ele=rep(1,12), 
       twe=c(1,2,1,2,1,2,1,2,1,2,1,2), 
       thir=c("THiS","THAT34","T(&*(", "!!!","@$#","$Q%J","who","THIS","this","this","this","this"), 
       stringsAsFactors = FALSE) 
data 

colls <- c() 

    spec=c("$","%","&") 
    for(col in names(data)) { 
     if(length(strings[stringr::str_detect(data[,col], spec)]) >= 1){ 
      print("HORRAY") 
colls <- c(collls, col) 
     } 
     else print ("NOOOOOOOOOO") 
    } 


    for(col in names(data)) { 
     if(any(data[,col]) %in% spec){ 
     print("HORRAY") 
colls <- c(collls, col) 
     } 
     else print ("NOOOOOOOOOO") 
    } 

Может ли кто-нибудь пролить свет на хороший способ решить эту проблему.

EDIT:

Конечной целью является, чтобы иметь вектор с именем имен столбцов, которые отвечают этим критериям. Извините за мой плохой С.О. вопрос, но, надеюсь, это поможет с тем, что я пытаюсь сделать

+0

Есть ли смысл иметь данные в столбцах, а не как строки (одна строка в строке)? – Gregor

+0

Вот как это делается, и мне также придется перебирать логические, числовые и т. Д. Столбцы. Я предполагаю, что я мог бы извлечь их и сохранить в виде вектора, но в конце дня цель состоит в том, чтобы получить имя столбца для переменной, которая содержит специальный символ и т. Д. – AGUY

+0

Обычно вы получаете лучшие результаты, если вы включаете цель вашего «конца дня» в вашем вопросе. – Gregor

ответ

1

Я разрушится данные в строки (одна строка для каждой строки)

strings = apply(data, 1, paste, collapse = "") 
contains_only_caps = strings == toupper(strings) 
strings[contains_only_caps] 
# [1] "33BB3BBB3.52 212THAT34" "55DD5DDD5.33 311T(&*(" "11EA1EAA1.44 412!!!" "33FB3FBB3.11 [email protected]$#" 
# [5] "55GD5GDD5.33 612$Q%J" "33IB3IBB3.66 812THIS" 


# escaping special characters 
spec=c("\\$","%","\\&") 
contains_spec = stringr::str_detect(strings, pattern = paste(spec, collapse = "|")) 

strings[contains_spec] 
# [1] "55DD5DDD5.33 311T(&*(" "33FB3FBB3.11 [email protected]$#" "55GD5GDD5.33 612$Q%J" 

Вы также могли бы использовать which на contains_spec или contains_only_caps, чтобы получить соответствующие номера строк для исходного кадра данных. Я думаю, что использование строк, а не строк данных, будет намного быстрее - пока вы хотите искать целые строки, а не определенные столбцы для определенных условий.

2

Я бы использовал grep() для поиска интересующей вас картины. См. here.

[:upper:] Соответствует любым строчным буквам.

Сочетание его с якорями (^, $) и совпадением одного или нескольких раз (+) дает ^[[:upper:]]+$ и должно полностью соответствовать записям полностью в столицах.

Следующие будет соответствовать специальным символам в данных игрушечном наборе (но не гарантировано соответствовать всем специальным символам в ваших реальных данных устанавливаются форма т.е. каналов, возврат каретки)

[:punct:] #Matches пунктуация - "# $% & '() * +, - /:; < => @ [\]^_` {|} ~

Обратите внимание, что вместо того, чтобы использовать [:punct:] вы могли бы определить свои специальные символы вручную.?..

Мы можем попробовать результирующий код на первой строке набора данных:.

#Using grepl() rather than grep() so that we return a list of logical values. 
grepl(x= data[1,], pattern = "^[[:upper:]]+$|[[:punct:]]") 
[1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE 

Это дает нам наш ожидаемый ответ на колонке девять, который имеет значение 1,24, кроме Здесь десятичная точка признается в качестве пунктуация и помечена как совпадение. Мы можем добавить «отрицательное утверждение», - (?!\\.) - удалить любые периоды с рассмотрения, прежде чем они будут даже проверены на то, что они являются символами пунктуации. Обратите внимание, что мы используем \, чтобы избежать периода.

grepl(x= data[1,], perl = TRUE, pattern = "(?!\\.)(^[[:upper:]]+$|[[:punct:]])") 
[1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE 

Это возвращает лучший ответ - теперь он больше не соответствует десятичным знакам. ПРИМЕЧАНИЕ. Возможно, это не так, как вы хотите, поскольку этот шаблон также не будет соответствовать полному стопу в полях символов. Вам нужно будет уточнить шаблон дальше.

Вместо того, чтобы использовать цикл «для цикла», чтобы повторить этот код по каждой строке в вашем фреймворке данных, вместо этого я бы использовал вместо вектора «больше».

Чтобы сделать это, мы должны преобразовать наш скрипт в функцию, которую мы будем называть с (применяются)

myFunction <- function(x){ 
     matches <- grepl(x= x, perl = TRUE, pattern = "(?!\\.)(^[[:upper:]]+$|[[:punct:]])") 
    #Given a set of logical vectors 'matches', is at least one of the values true? using any() 
    return(any(matches)) 
} 

apply(X = data, 1, myFunction) 

1-выше инструктирует применить(), чтобы подтвердить по строкам, а не столбцам.

[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 

В вашем примере набор данных всех строк содержит запись, содержащую специальный символ или строку всех прописных букв. Это неудивительно, так как многие столбцы в вашем наборе данных примера представляют собой список одиночных заглавных букв.

Если вы просто заинтересованы в которых значение в столбце тринадцать соответствует установленным критериям вы можете использовать:

matches <- grepl(x= data$thir, perl = TRUE, pattern = "(?!\\.)(^[[:upper:]]+$|[[:punct:]])") 
matches 
[1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE 

Для подмножества вашей dataframe на соответствующих строках:

data[matches,] 
    one two thr fou fiv six sev eig nin ten ele twe thir 
3 5 5 D D 5 D D D 5.33 3 1 1 T(&*(
4 1 1 E A 1 E A A 1.44 4 1 2 !!! 
5 3 3 F B 3 F B B 3.11 5 1 1 @$# 
6 5 5 G D 5 G D D 5.33 6 1 2 $Q%J 
8 3 3 I B 3 I B B 3.66 8 1 2 THIS 

Для подмножества вашей dataframe на несоответствующие строки:

data[!matches,] 
    one two thr fou fiv six sev eig nin ten ele twe thir 
1 1 1 A A 1 A A A 1.24 1 1 1 THiS 
2 3 3 B B 3 B B B 3.52 2 1 2 THAT34 
7 1 1 H A 1 H A A 1.55 7 1 1 who 
9 5 5 J D 5 J D D 5.33 9 1 1 this 
10 1 1 H A 1 H A A 1.32 10 1 2 this 
11 3 3 I B 3 I B B 3.54 11 1 1 this 
12 5 5 J D 5 J D D 5.77 12 1 2 this 

Обратите внимание, что используемое регулярное выражение не соответствует T HAT34, поскольку он не составлен полностью заглавными буквами, с номером 34 в конце.

EDIT:

Чтобы получить список имен столбцов, идентифицирующие столбцы, которые удовлетворяют критерии в вашем использовании myFunction редактирования, описанном выше:

colnames(data)[apply(X = data, 2, myFunction)] 
"thr" "fou" "six" "sev" "eig" "thir" 

Число в применить() изменяется от 1 до 2 для повторения столбцов, а не строк. Мы передаем результат из apply(), списка логических совпадений (TRUE или FALSE), в colnames (data) - это возвращает соответствующие имена столбцов через подмножество.

Смежные вопросы