Выбор строк с одинаковым результатом в разных столбцах в R

Я хотел бы выбрать в своем кадре данных (улавливать) только те строки, для которых моя переменная «tspp.name» совпадает с моей переменной «elasmo.name».

Например, в этом случае будут выбраны строки #74807 и #74809, но не строка #74823, потому что elasmo.name — «скейт», а tspp.name — «северная креветка».

Я уверен, что для этого есть простой ответ, но я еще не нашел его. Любые подсказки будут оценены.

> catch[4:6,]
      gear tripID obsID sortie setID       date     time NAFO    lat   long      dur depth bodymesh
74807 GRL2 G00001     A      1    13 2000-01-04 13:40:00   2H 562550 594350 2.000000   377       80
74809 GRL2 G00001     A      1    14 2000-01-04 23:30:00   2H 562550 594350 2.166667   370       80
74823 GRL2 G00001     A      1    16 2000-01-05 07:45:00   2H 561450 593050 3.000000   408       80
      codendmesh mail.fil long.fil nbr.fil hook.shape hook.size hooks VTS tspp       tspp.name elasmo
74807         45       NA       NA      NA                   NA    NA 3.3 2211 Northern shrimp   2211
74809         45       NA       NA      NA                   NA    NA 3.2 2211 Northern shrimp   2211
74823         45       NA       NA      NA                   NA    NA 3.3 2211 Northern shrimp    211
          elasmo.name kept discard Tcatch     date.1 latitude longitude       EID
74807 Northern shrimp 2747      50   2797 2000-01-04 56.91667 -60.21667 G00001-13
74809 Northern shrimp 4919     100   5019 2000-01-04 56.91667 -60.21667 G00001-14
74823          Skates    0      50     50 2000-01-05 56.73333 -60.00000 G00001-16
                                 fgear
74807 Shrimp trawl (stern) with a grid
74809 Shrimp trawl (stern) with a grid
74823 Shrimp trawl (stern) with a grid

person GodinA    schedule 08.06.2012    source источник
comment
Делает ли catch[with(catch, tspp.name==elasmo.name),] то, что вы хотите?   -  person Justin    schedule 08.06.2012
comment
или catch[catch$tspp.name == catch$elasmo.name,] в этом отношении.   -  person Justin    schedule 08.06.2012
comment
Разница между ответами Брэндона и Джастина (второй) заключается в том, как обрабатываются значения NA, если они появляются либо в tspp.name, либо в elasmo.name.   -  person Brian Diggs    schedule 08.06.2012
comment
subset(catch, tspp.name ==elasmo.name), как и подход which, не имеет проблемы, заключающейся в том, что NA возвращают несовпадающие строки всякий раз, когда любое из обоих проверенных значений является NA.   -  person IRTFM    schedule 09.06.2012
comment
Спасибо всем за ответы. Однако я получаю то же сообщение об ошибке: Ошибка в Ops.factor(tspp.name, elasmo.name): разные наборы факторов › str(catch$tspp.name) Factor с 18 уровнями Американская камбала,..: 10 10 10 10 10 10 10 10 10 10 ... › str(catch$elasmo.name) Фактор с 40 уровнями Американская камбала,..: 19 19 19 19 19 27 27 19 19 19 ... Есть ли обходной путь это?   -  person GodinA    schedule 09.06.2012


Ответы (1)


Я знаю, в чем проблема - вам нужно прочитать данные "как есть", добавив аргумент as.is=TRUE к команде read.csv (которую вы предположительно использовали для загрузки всего). Без этого строки сохраняются как факторы, и все предложенные выше методы не сработают (как вы обнаружили!)

После того, как вы правильно прочитали данные, вы можете использовать либо

catch[which(catch$tspp.name == catch$elasmo.name),]

or

subset(catch, tspp.name == elasmo.name)

чтобы получить совпадающие строки - не пропускайте which в первой строке, иначе код не будет работать при сравнении с NA.

Ниже приведен 30-секундный пример с использованием небольшого сфабрикованного набора данных, который явно иллюстрирует все эти моменты.

Во-первых, создайте текстовый файл на диске, который выглядит так (я сохранил его как "F:/test.dat", но его можно сохранить где угодно)...

col1~col2
a~b
a~a
b~b
c~NA
NA~d
NA~NA

Давайте загрузим его без преобразования факторов в строки, просто чтобы увидеть, как методы, предложенные выше, не работают:

> dat=read.csv("F:/test.dat",sep="~")  # don't forget to check the filename

> dat[which(dat$col1==dat$col2),]
Error in Ops.factor(dat$col1, dat$col2) : level sets of factors are different

> dat[dat$col1==dat$col2,]
Error in Ops.factor(dat$col1, dat$col2) : level sets of factors are different

> subset(dat,col1==col2)
Error in Ops.factor(col1, col2) : level sets of factors are different

Это именно та проблема, с которой вы столкнулись. Если вы наберете dat$col1 и dat$col2, вы увидите, что первый имеет уровни фактора a b c, а второй имеет уровни фактора a b d — отсюда и сообщения об ошибках.

Теперь давайте сделаем то же самое, но на этот раз прочитаем данные «как есть»:

> dat=read.csv("F:/test.dat",sep="~",as.is=TRUE)  # note the as.is=TRUE

> dat[which(dat$col1==dat$col2),]
  col1 col2
2    a    a
3    b    b

> dat[dat$col1==dat$col2,]
     col1 col2
2       a    a
3       b    b
NA   <NA> <NA>
NA.1 <NA> <NA>
NA.2 <NA> <NA>

> subset(dat,col1==col2)
     col1 col2
2    a    a
3    b    b

Как видите, и первый метод (на основе which), и третий метод (на основе subset) дают правильный ответ, а второй метод путается при сравнении с NA. Я бы лично поддержал метод subset, так как, на мой взгляд, он самый аккуратный.

Последнее замечание: есть и другие способы получить строки, возникающие как факторы во фрейме данных, и, чтобы избежать всех этих головных болей, всегда не забывайте включать аргумент stringsAsFactors = FALSE в конце всякий раз, когда вы создаете фрейм данных, используя data.frame. Например, правильный способ создать объект dat непосредственно в R:

dat=data.frame(col1=c("a","a","b","c",NA,NA), col2=c("b","a","b",NA,"d",NA),
                         stringsAsFactors=FALSE)

Введите dat$col1 и dat$col2, и вы увидите, что они были правильно интерпретированы. Если вы попробуете еще раз, но с опущенным аргументом stringsAsFactors (или установленным в TRUE), вы увидите появление этих проклятых факторов (точно так же, как хитрый первый метод загрузки с диска).

Короче говоря, всегда помните as.is=TRUE и stringsAsFactors=FALSE и научитесь использовать команду subset, и вы не ошибетесь!

Надеюсь это поможет :)

person Tim P    schedule 10.06.2012
comment
Фантастический ответ @TimP большое спасибо за все ваши подробности. - person GodinA; 11.06.2012