【问题标题】:Remove rows whose values across columns contain more than 2 of 4 unique characters删除跨列的值包含超过 4 个唯一字符中的 2 个的行
【发布时间】:2014-01-22 15:19:03
【问题描述】:

希望标题的措辞有意义。我有一个由值组成的数据框:“A”、“B”、“C”、“D”、“”、“A/B”。我想确定哪些行仅包含“A”、“B”、“C”或“D”中的 2 个。行中每个字母的频率无关紧要。我只想知道这 4 个字母中是否有超过 2 个存在于该行中。

这是一个示例数据框:

    df.sample = as.data.frame(rbind(c("A","B","A","A/B","B","B","B","B","","B"),c("A","B","C","A","B","","","B","","B"),c("A","B","D","D","B","B","B","B","","B"),c("A","B","A","A","B","B","B","B","B","B")))
    df.sample

      V1 V2 V3  V4 V5 V6 V7 V8 V9 V10
    1  A  B  A A/B  B  B  B  B      B
    2  A  B  C   A  B        B      B
    3  A  B  D   D  B  B  B  B      B
    4  A  B  A   A  B  B  B  B  B   B

我想对每一行应用一个函数来确定 4 个字母(“A”、“B”、“C”或“D”)中的每一个存在多少,而不是每个字母的频率,而是本质上“A”、“B”、“C”和“D”只有 0 或 1 值。如果这 4 个值的总和 > 3,那么我想将该行的索引分配给一个新向量,该向量将用于从数据框中删除这些行。

    myfun (x){
      #which rows contain > 2 different letters of A, B, C, or D.
      #The number of times each letter occurs in a given row does not matter. 
      #What matters is if each row contains more than 2 of the 4 letters. Each row should only contain 2 of them. The combination does not matter.

      out = which(something > 2)
    }

    row.indexes = apply(df.sample,1,function(x) myfun(x)) #Return a vector of row indexes that contain more than 2 of the 4 letters.

    new.df.sample = df.sample[-row.indexes,] #create new data frame excluding rows containing more than 2 of the 4 letters.

在上面的 df.sample 中,第 2 行和第 3 行包含这 4 个字母中的 2 个以上,因此应将其编入索引以进行删除。通过函数运行 df.sample 并删除 row.indexes 中的行后,我的 new.df.sample 数据框应如下所示:

      V1 V2 V3  V4 V5 V6 V7 V8 V9 V10
    1  A  B  A A/B  B  B  B  B      B
    4  A  B  A   A  B  B  B  B  B   B

我试图将此视为 4 个字母中的每一个的逻辑语句,然后为每个字母分配 0 或 1,将它们相加,然后确定哪些总和 > 2。例如,我认为也许我可以尝试 'grep()' 并将其转换为每个字母的逻辑,然后将其转换为 0 或 1 并求和。这似乎太长了,并且不适合我尝试的方式。有什么想法吗?

【问题讨论】:

  • 对于 A/B,忽略它是“A/B”,只检查该值是否包含 A、B、C 或 D。单元格内的值不必是一个完美的匹配,但只包含我正在寻找的价值。例如,如果第 1 行中的 A/B 实际上是 A/C,则该行将被索引以删除,但由于它是 A/B,它会保留。

标签: r dataframe apply


【解决方案1】:

这是这个任务的一个函数。该函数返回一个逻辑值。 TRUE 表示具有两个以上不同字符串的行:

myfun <- function(x) {
  sp <- unlist(strsplit(x, "/"))
  length(unique(sp[sp %in% c("A", "B", "C", "D")])) > 2
}

row.indexes <- apply(df.sample, 1, myfun)
# [1] FALSE  TRUE  TRUE FALSE

new.df.sample <- df.sample[!row.indexes, ] # negate the index with '!'

#   V1 V2 V3  V4 V5 V6 V7 V8 V9 V10
# 1  A  B  A A/B  B  B  B  B      B
# 4  A  B  A   A  B  B  B  B  B   B

【讨论】:

  • @SC2 我更新了函数。现在,它也适用于 A/B 案例。
猜你喜欢
  • 2011-07-04
  • 2017-10-16
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多