2012-06-08 43 views
1

我想仅在我的数据框(catch)中选择我的“tspp.name”变量与我的“elasmo.name”变量相同的行。在R的不同列中选择具有相同结果的行

例如,在这种情况下,行74807和#74809将被选中,但不是#74823行,因为elasmo.name是“skate”,tspp.name是“Northern shrimp”。

我确定有一个简单的答案,但我还没有找到它。任何提示将不胜感激。

> 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 
+0

'catch(with(catch,tspp.name == elasmo.name),''做你想做的事吗? – Justin

+2

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

+0

或catch [catch $ tspp.name == catch $ elasmo.name,]'。 – Justin

回答

2

我知道是什么问题 - 你需要在数据读取“原样”,通过添加参数as.is=TRUEread.csv命令(你可能用来加载一切)。没有这一点,琴弦存储为因素,以及上文建议的所有方法都失败(如你发现!)

一旦你的数据正确读取,你可以使用

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

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

获得匹配的行 - 中的第一个为NAS做比较时,否则代码将失败不省略which

下面是一个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$col1dat$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 = FALSEdata.frame。举例来说,正确的方法为R中直接创建对象dat是:

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

类型dat$col1dat$col2,你会看到他们已经正确地解释。如果您再次尝试,但省略了stringsAsFactors参数(或设置为TRUE),则会看到这些不合理的因素出现(就像从磁盘加载的第一种方法一样)。

总之,永远记得as.is=TRUEstringsAsFactors=FALSE,并学习如何使用subset命令,你不会错得太远!

希望这会有所帮助:)

+0

梦幻般的答案@TimP非常感谢你的所有细节。 – GodinA

相关问题