【问题标题】:Filter dataframe with values from second dataframe [duplicate]使用来自第二个数据帧的值过滤数据帧[重复]
【发布时间】:2018-07-23 13:32:50
【问题描述】:

我有两个数据框 ab

a 可以是 2000-3000 行,15 列。

b 是一个小型数据框(2 列,150 行)。

下面是一个简化的数据集。

   a <- structure(list(ID = structure(c(1L, 2L, 1L, 3L, 2L, 1L, 3L), .Label = c("ID1", 
    "ID2", "ID3"), class = "factor"), score = structure(c(4L, 5L, 
    3L, 6L, 7L, 1L, 2L), .Label = c("10", "110", "20", "28", "34", 
    "80", "90"), class = "factor"), desc = structure(c(1L, 1L, 1L, 
    1L, 1L, 1L, 1L), class = "factor", .Label = "text")), .Names = c("ID", 
    "score", "desc"), row.names = c(NA, -7L), class = "data.frame")

  b <- structure(list(ID = structure(1:3, .Label = c("ID1", "ID2", "ID3"
), class = "factor"), cutoff = structure(1:3, .Label = c("12", 
"46", "54"), class = "factor")), .Names = c("ID", "cutoff"), row.names = c(NA, 
-3L), class = "data.frame")

我想使用数据框 b 中的分数过滤数据框 a。例如,在数据帧 b 中,ID“ID1”的截止值为 12,所以我只想让数据帧 a 中的 ID1 保持在 12 以上或等于 12。我想对所有 IDS 执行此操作。

> a
   ID score desc
1 ID1    28 text
2 ID2    34 text
3 ID1    20 text
4 ID3    80 text
5 ID2    90 text
6 ID1    10 text
7 ID3   110 text
> b
   ID cutoff
1 ID1     12
2 ID2     46
3 ID3     54

鉴于数据帧 b 中的截止值,最终数据帧 a 应保持如下:

> a
   ID score desc
1 ID1    28 text
2 ID1    20 text
3 ID3    80 text
4 ID2    90 text
5 ID3   110 text

【问题讨论】:

  • 你试过什么?这是一个简单的合并和过滤问题,请参阅一些教程。另外,请将数字存储为数字。

标签: r


【解决方案1】:

以 R 为基数:

subset(merge(a,b),as.numeric(as.character(score)) > as.numeric(as.character(cutoff)),1:3)
#    ID score desc
# 1 ID1    28 text
# 2 ID1    20 text
# 5 ID2    90 text
# 6 ID3    80 text
# 7 ID3   110 text

或者使用 dplyr:

library(dplyr)
a %>%
  left_join(b) %>%
  filter(as.numeric(as.character(score)) > as.numeric(as.character(cutoff))) %>%
  select(-cutoff)

#    ID score desc
# 1 ID1    28 text
# 2 ID1    20 text
# 3 ID3    80 text
# 4 ID2    90 text
# 5 ID3   110 text

【讨论】:

  • 固定的谢谢,在里面插入as.character
【解决方案2】:

这是一个基本的 R 选项:

df <- merge(a, b, by="ID")
index <- as.numeric(levels(df$score))[df$score] >
    as.numeric(levels(df$cutoff))[df$cutoff]
df[index, -which(names(df) %in% c("cutoff"))]

   ID score desc
1 ID1    28 text
2 ID1    20 text
5 ID2    90 text
6 ID3    80 text
7 ID3   110 text

Demo

注意:将您的因子分数和截止值转换为数值需要做一些工作。除非您计划有许多重复值,否则请考虑使用数字类型来存储此信息。

【讨论】:

    【解决方案3】:

    您可以尝试以下方法。我们首先将 score 和 cutoff 列转换为数值,因为它们现在是因子。然后我们从数据帧中提取子集,使用matcha 中的每个条目从b 中找到相应的截止值。

    a$score = as.numeric(as.character(a$score))
    b$cutoff= as.numeric(as.character(b$cutoff))
    subset(a,score>=b$cutoff[match(a$ID,b$ID)])
    

    输出:

       ID score desc
    1 ID1    28 text
    3 ID1    20 text
    4 ID3    80 text
    5 ID2    90 text
    7 ID3   110 text
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多