子集化的规则

时间:2013-01-30 11:53:09

标签: r

df1df2如下:

df1 <- read.table(text =" x y z
                          1 1 1
                          1 2 1
                          1 1 2
                          2 1 1
                          2 2 2",header=TRUE)

df2 <- read.table(text =" a b c
                          1 1 1
                          1 2 8
                          1 1 2
                          2 6 2",header=TRUE)

我可以向数据询问一些类似的事情:

 df2[ df2$b == 6 | df2$c == 8 ,] #any rows where b=6 plus c=8 in df2
 #and additive conditions
 df2[ df2$b == 6 & df2$c == 8 ,] # zero rows

在data.frame:

之间
 df1[ df1$z %in% df2$c ,] # rows in df1 where values in z are in c (allrows)

这给了我所有的行:

 df1[ (df1$x %in%  df2$a) &
      (df1$y %in%  df2$b) &
      (df1$z %in%  df2$c) ,]

但是这不应该给我df1的所有行:

 df1[ df1$z %in% df2$c | df1$b == 9,]

我真正希望做的是在三个列条件下对df1 df2进行分组, 所以我只得到df1中的行,其中a,b,c在一行中同时等于x,y,z。在实际数据中,我将有超过3列,但我仍然希望在3个添加柱条件下进行子集。

因此,在df1上对我的示例数据df2进行子集化,我的结果将是:

df1
   1 1 1
   1 1 2

使用语法更加困惑而且SO帖子都是我想要的变化,这实际上会让我更加困惑。

我发现我可以这样做:

 merge(df1,df2, by.x=c("x","y","z"),by.y=c("a","b","c"))

它给了我我想要的东西,但我想理解为什么我的[次尝试错了。

1 个答案:

答案 0 :(得分:6)

除了使用merge的好解决方案(感谢您,我总是忘记merge),这可以使用?interaction在基础上实现,如下所示。可能还有其他变化,但这是我熟悉的那个:

> df1[interaction(df1) %in% interaction(df2), ]

现在回答你的问题:首先,我认为有一个拼写错误(已更正):

df1[ df1$z %in% df2$c | df2$b == 9,] # second part should be df2$b == 9

您会收到错误,因为第一部分评估为

[1] TRUE TRUE TRUE TRUE TRUE

,第二个评估为:

[1] FALSE FALSE FALSE FALSE

您对获得错误的不等长度执行|操作:

longer object length is not a multiple of shorter object length

修改:如果您有多列,则可以选择此类交互。例如,如果您想从df1获取前两列与df2匹配的行,那么您可以这样做:

> df1[interaction(df1[, 1:2]) %in% interaction(df2[, 1:2]), ]