如何根据列的组合选择行

时间:2012-11-05 13:05:11

标签: r select dataframe rows

我有以下数据框:

structure(list(Species = 1:4, Ni = c(1, NA, 1, 1), Zn = c(1, 
1, 1, 1), Cu = c(NA, NA, 1, NA)), .Names = c("Species", "Ni", 
"Zn", "Cu"), row.names = c(NA, -4L), class = "data.frame")

我希望得到一个包含Ni = 1Zn = 1Cu = NA所有物种的向量。所以在这个例子中将是(1,4)

我以为我可以尝试使用R脚本select * from where,但我似乎无法在RStudio(R版本2.15.1)上安装RMySQL包。

4 个答案:

答案 0 :(得分:4)

df <- structure(list(Species=1:4,Ni=c(1,NA,1,1),Zn=c(1,1,1,1),Cu=c(NA,NA,1,NA)),
      .Names=c("Species","Ni","Zn","Cu"),row.names=c(NA,-4L),class="data.frame")

with(df, Species[Ni %in% 1 & Zn %in% 1 & Cu %in% NA])
[1] 1 4

您应该使用Ni == 1而不是Ni %in% 1,因为前者将返回NA Ni NA元素。 Cu %in% NA生成与is.na(Cu)相同的结果。

with(df, Species[Ni == 1 & Zn %in% 1 & Cu %in% NA])
[1] 1 NA 4

请注意,Ni == 1中使用的subset与@ MadScone的答案一样,不会受此影响(这对我来说是一个惊喜)。

subset(df, Ni == 1 & Zn == 1 & is.na(Cu), Species)
  Species
1       1
4       4

答案 1 :(得分:2)

看看subset()。

x <- structure(list(Species = 1:4, Ni = c(1, NA, 1, 1), Zn = c(1, 
     1, 1, 1), Cu = c(NA, NA, 1, NA)), .Names = c("Species", "Ni", 
     "Zn", "Cu"), row.names = c(NA, -4L), class = "data.frame")

subset(x, Ni == 1 & Zn == 1 & is.na(Cu), Species)

答案 2 :(得分:0)

修改
我的立场由Backlin ...更正了 使用%in%而不是== x & !is.na() 更好MadScone建议使用subset() 更好,因为结果仍然是data.frame,即使只选择一列输出,即

> class(subset(df, Ni == 1 & Zn == 1 & is.na(Cu), Species))
[1] "data.frame"
#whereby we get a vector when only one column is selected...
> class(df[df$Ni %in% 1 & df$Zn %in% 1 & is.na(df$Cu), 1])
[1] "integer"
# but we get data.frame when using multiple columns...
> class(df[df$Ni %in% 1 & df$Zn %in% 1 & is.na(df$Cu), 1:2])
[1] "data.frame"


我只是离开我的低于标准答案提及这个替代习语,因为一个人应该避免

设定:

>  df <- structure(list(Species = 1:4, Ni = c(1, NA, 1, 1), Zn = c(1, 
    1, 1, 1), Cu = c(NA, NA, 1, NA)), .Names = c("Species", "Ni", 
    "Zn", "Cu"), row.names = c(NA, -4L), class = "data.frame")
> df
  Species Ni Zn Cu
1       1  1  1 NA
2       2 NA  1 NA
3       3  1  1  1
4       4  1  1 NA

查询:

>  df[df$Ni == 1 & !is.na(df$Ni) 
      & df$Zn == 1 & !is.na(df$Zn) 
      & is.na(!df$Cu), ]

  Species Ni Zn Cu
 1       1  1  1 NA
 4       4  1  1 NA

NA值的技巧是明确地排除它们,例如使用Ni,请求值1和!is.na()等。如果不这样做,将导致找到记录,例如,Ni是NA

如上所述,df[df$Ni %in% 1 & df$Zn %in% 1 & is.na(!df$Cu), ]成语更为可取,使用subset()通常更好。

> df[df$Ni == 1 & df$Zn == 1 & is.na(!df$Cu), ]
   Species Ni Zn Cu
1        1  1  1 NA
NA      NA NA NA NA       # OOPS...
4        4  1  1 NA

答案 3 :(得分:0)

df <- structure(list(Species = 1:4, Ni = c(1, NA, 1, 1), Zn = c(1, 1, 1, 1),
                     Cu = c(NA, NA, 1, NA)),
                .Names = c("Species", "Ni", "Zn", "Cu"), row.names = c(NA, -4L),
                class = "data.frame")

如果列NiZnCu仅包含1NA,您只需使用:

subset(df, Ni & Zn & is.na(Cu), Species)