2014-08-22 5 views
1

Я пытаюсь написать код, который будет анализировать через один столбец, содержащий несколько фрагментов информации. Так, например, сказать, что я следующий кадр данных называется ДФ:Анализ данных по нескольким строкам в R

ids    info 
1 101  red;circle 
2 103  circle;blue 
3 122  red;green 
4 102 circle;red;green 
5 213    blue 
6 170   red;blue 

Когда я запускаю таблицу (DF), вы получите следующее:

table(df) 
     info 
    ids blue circle;blue circle;red;green red;blue red;circle 
     101 0   0    0  0   1 
     102 0   0    1  0   0 
     103 0   1    0  0   0 
     122 0   0    0  0   0 
     170 0   0    0  1   0 
     213 1   0    0  0   0 
     info 
    ids red;green 
     101   0 
     102   0 
     103   0 
     122   1 
     170   0 

    213   0 

То, что я хотел бы сделать, это: 1. Перерыв столбец info в 2 столбца, один для формы и один для цвета и 2. Присвойте любой идентификатор, который имеет более одного цвета, будет «многоцветным». Поэтому я написал следующее:

df$shape <- as.character(df$info) 
for (i in 1:dim(df)[1]){ 
    if (grepl("circle",df$info[i])==TRUE) { 
    df$shape[i] <- "circle" 
    } else if (grepl("circle",df$info[i])==FALSE) { 
    df$shape[i]<-NA} 
} 
for (i in 1:dim(df)[1]){ 
    if (grepl(";",df$info[i])==TRUE) { 
    df$info[i] <- "Multicolored" 
    } else {df$info[i]<-df$info[i]} 
} 

Из этого кода я получаю вывод:

df 
    ids   info shape 
1 101 Multicolored circle 
2 103 Multicolored circle 
3 122 Multicolored <NA> 
4 102 Multicolored circle 
5 213   blue <NA> 
6 170 Multicolored <NA> 

Как мой код написан, он говорит, что экземпляр, как 101 red;circle многоцветный, когда на самом деле это а не просто красный и круг. Каков правильный способ анализа этих данных, когда «круг» может отображаться в колонке info в начале, середине или в конце. Любые предложения приветствуются, и спасибо!

+0

У вас есть только одна форма? – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto в данный момент да, у меня только одна форма, но она может легко иметь несколько фигур. Еще один экземпляр, который у меня может быть, - это запись, подобная кругу 203, поэтому не будет цвета, просто формы. – Archimeow

ответ

1

С этим типом проблемы может иметь смысл разделить строки на ;, а затем работать с векторами символьных строк. Например,

mystrings <- strsplit(df$info,";") 
getStrings <- function(x,s,none=NA_character_,multiple="Multicolored") 
    switch(sum(x%in%s)+1,none,x[x%in%s],multiple,multiple) 
df$shape <- sapply(mystrings,FUN=getStrings,s=c("circle")) 
df$color <- sapply(mystrings,FUN=getStrings,s=c("red","green","blue")) 

Я лично считаю этот подход более простым, чем попытка работать с чистыми регулярными выражениями и операторами if.

+0

Благодарим вас за ответ. Использование «переключателя» было чем-то, о чем я не думал. Я все еще относительно новичок в R, и это будет функция, которую я часто использую. – Archimeow

0

Мне понравился ответ @farnsy, но я хотел бы также опубликовать свое решение, которое в корне похоже, но не требует указания цветов (предполагая, что все не фигуры - это цвета).

# Load the data 
df <- read.table(textConnection('ids    info 
1 101  red;circle 
2 103  circle;blue 
3 122  red;green 
4 102 circle;red;green 
5 213    blue 
6 170   red;blue'),stringsAsFactors=FALSE) 

# Split your column. 
split.col <- strsplit(df$info,';') 
# Specify which words are considered shapes. 
shapes <- c('circle') # Could include more 
# Find which rows had shapes. 
df$shape <- sapply(split.col, function(x) x[match(shapes,x)[1]]) # Only selct one shape 
# The rest must be colours, count them. 
num.colours <- sapply(split.col, function(x) length(setdiff(x, shapes))) 
df$multicoloured <- num.colours > 1 

df 
# ids    info shape multicoloured 
# 1 101  red;circle circle   FALSE 
# 2 103  circle;blue circle   FALSE 
# 3 122  red;green <NA>   TRUE 
# 4 102 circle;red;green circle   TRUE 
# 5 213    blue <NA>   FALSE 
# 6 170   red;blue <NA>   TRUE 
0

Вы также можете попробовать:

pat1 <- paste0(c("red","blue", "green"), collapse="|") 
shape1 <- gsub(paste(pat1, ";", sep="|"), "", df$info) 
shape1[shape1==''] <- NA 
df[,c("info", "shape")] <- as.data.frame(do.call(rbind, 
       Map(`c`, lapply(regmatches(df$info, gregexpr(pat1, df$info)), function(x) { 
      if(length(x)>1) "Multicolored" else x}), shape1)), stringsAsFactors=FALSE) 

df 
# ids   info shape 
#1 101   red circle 
#2 103   blue circle 
#3 122 Multicolored <NA> 
#4 102 Multicolored circle 
#5 213   blue <NA> 
#6 170 Multicolored <NA> 
Смежные вопросы