【问题标题】:Conditional Subsetting based on column numbers基于列号的条件子集
【发布时间】:2017-05-31 18:54:21
【问题描述】:

当列不匹配时,我需要对数据进行子集化。例如,如果我在第一列 X 中有一个标识符,例如 1,那么 Y 列中的以下所有示例都应该匹配:

X <- rep(1:4, times=2, each=2)
Y <- rep(c("Dave","Sam","Sam","Sam"))
Z <- as.data.frame(cbind(X,Y))
head(Z)

因此,在此示例中,我想在 X = 1 和 3 时对数据进行子集化,因为 y 列与第 2 列的子集不完全一致。为这种类型获取子集函数会很棒我在更大的数据帧上遇到的问题

谢谢,

【问题讨论】:

  • Z[Z$X %in% c(1,3),]?
  • 我希望能够为满足此条件的所有条件执行此操作,但这只是一个小的说明性示例,但谢谢。
  • 你想要的输出是什么?
  • 我用 sqldf 用下面的代码弄明白了:AA &lt;- sqldf("select X, count (distinct(Y)) as distinct_names From Z Group By X Having count (distinct(Y)) &gt; 1 Order by X") AB &lt;- Z %&gt;% inner_join(AA) AB &lt;- AB %&gt;% select(X, Y) AB 那样很笨拙,想看看它是否能更好地工作
  • 好吧,如果它有效,请使用它。如果您想在没有 SQL 的情况下查看更多 R 方法,请参阅下面的答案。不确定哪个更有效。

标签: r function subset


【解决方案1】:

dplyr:

df <- data.frame(x = rep(1:4, times=2, each=2),
                 y = rep(c("Dave","Sam","Sam","Sam")))

library(dplyr)

df %>% 
  group_by(x) %>% 
  filter(any(!y == lag(y), na.rm = T))

#> Source: local data frame [8 x 2]
#> Groups: x [2]
#> 
#>       x      y
#>   <int> <fctr>
#> 1     1   Dave
#> 2     1    Sam
#> 3     3   Dave
#> 4     3    Sam
#> 5     1   Dave
#> 6     1    Sam
#> 7     3   Dave
#> 8     3    Sam

我测试了一些案例,不确定这是否包含很多边缘案例

【讨论】:

  • 这行得通,我在我更大的数据框上测试了它,它是等效的,谢谢!
【解决方案2】:

这是我会做的方式,尽管可能有更优雅的方式。这是你需要的吗?

X <- rep(1:4, times=2, each=2)
Y <- rep(c("Dave","Sam","Sam","Sam"))
Z <- as.data.frame(cbind(X,Y))
head(Z)

# First Create Concatenated column
Z$XY <- paste(Z$X, Z$Y)

# Eliminate all duplicates
Z_unique <- unique(Z)

# Find number of occurences of each X value
n_occur <- data.frame(table(Z_unique$X))

# Pull only those that have occurred more than once
n_occur[n_occur$Freq > 1,]

# Subset the output to only those values
output <- Z[Z$X %in% n_occur$Var1[n_occur$Freq > 1],]

【讨论】:

    【解决方案3】:

    我们可以使用data.table

    library(data.table)
    setDT(df)[, .SD[any(!y == shift(y))], x]
    #   x    y
    #1: 1 Dave
    #2: 1  Sam
    #3: 1 Dave
    #4: 1  Sam
    #5: 3 Dave
    #6: 3  Sam
    #7: 3 Dave
    #8: 3  Sam
    

    数据

    df <- data.frame(x = rep(1:4, times=2, each=2),
                  y = rep(c("Dave","Sam","Sam","Sam")))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 2018-04-23
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      • 2022-08-18
      • 2020-04-11
      相关资源
      最近更新 更多