【发布时间】:2021-07-15 09:41:43
【问题描述】:
我想根据列中的值删除数据框中的行,这些值在使用 R 基础的列表中找不到。
我有一个简化的数据框,如下所示:
> df
Category.1 Value.1 Category.2 Value.2
A 0.1 A 0.1
A 0.1 A 0.2
A 0.1 A 0.3
A 0.1 B 0.6
A 0.1 B 0.7
A 0.1 B 0.8
A 0.1 C 0.5
A 0.1 C 0.8
A 0.1 C 0.9
. . . .
B 0.3 A 0.1
B 0.4 A 0.2
B 0.5 A 0.3
B 0.1 B 0.6
B 0.2 B 0.7
B 0.3 B 0.8
B 0.3 C 0.5
B 0.8 C 0.8
B 0.6 C 0.9
. . . .
Z 0.1 X 0.1
Z 0.1 X 0.3
Z 0.1 X 0.4
Z 0.1 Y 0.6
Z 0.1 Y 0.8
Z 0.1 Y 0.4
Z 0.1 Z 0.2
Z 0.1 Z 0.1
Z 0.1 Z 0.6
我有一个列表,每个类别有四个值:
> List
A 0.1 0.2 0.3 0.4
B 0.3 0.4 0.5 0.6
C 0.5 0.6 0.8 0.9
. . . . .
Z 0.1 0.2 0.3 0.4
我想过滤满足特定条件的行的数据框。更具体地说,我想保留具有相同 Category 的行,独立于它们的 Value,以及不具有相同 Category 的行,但它们的值分别在列表中找到。
简化:删除行,其中
Category.1 不等于 Category.2
AND Value.1不在与Category.1名称匹配的列表中
或Value.2不在与Category.2名称匹配的列表中
只要在列表中未找到 Category.1 或 Category.2 中的值之一,并且 Category.1 和 Category.2 不同,则删除该行。
现在,通过dplyr 找到解决方案非常简单,但我需要在R base 中找到解决方案。这是有效的dplyr 方法:
dyplr 示例(工作):
df %>% rowwise() %>%
filter(ifelse(Category.1 == Category.2,
Category.1 == Category.2,
Value.1 %in% List[[Category.1]] &
Value.2 %in% List[[Category.2]]))
我还能够通过循环遍历每一行在R base 中提出解决方案,但这不是最有效的方法,尤其是对于具有 > 10 000 行的数据框,它需要的时间太长了。
R 基础示例(工作,但速度慢):
df[sapply(1:nrow(df), function(x) (df[x,"Category.1"] == df[x,"Category.2"] |
df[x,"Category.1"] != df[x,"Category.2"] &
df[x,"Value.1"] %in% List[[match(df[x,"Category.1"],names(List))]] &
df[x,"Value.2"] %in% List[[match(df[x,"Category.2"], names(List))]])),]
由于我的主要目标是对数据进行子集化,因此我尝试使用subset(),并使用以下表达式:
subset() 方法(不起作用):
subset(df, Category.1 == Category.2 |
Category.1 != Category.2 &
Value.1 %in% List[match(Category.1, names(List)][[1]] &
Value.2 %in% List[match(Category.2, names(List)][[1]])
这只选择Category.1 == Category.2。不确定,为什么它不起作用。有人有想法吗?
有没有更好的解决方案?
如果有帮助,这里是代表数据框和列表的代码:
示例数据:
df <- data.frame(Category.1 = rep(LETTERS, each = 7), Value.1 = rep(seq(0.2, 0.8, 0.1), length(LETTERS)),
Category.2 = sample(rep(LETTERS, each = 7)), Value.2 = rep(rev(seq(0.2, 0.8, 0.1)), length(LETTERS)))
List <- setNames(lapply(LETTERS, function(x) c(0.2, 0.3, 0.6, 0.8)), LETTERS)
为简单起见,列表中的值都相同。
【问题讨论】:
-
如果你放弃坚持使用base R,我建议
anti_join -
您打印
List的方式看起来像是data.frame,甚至可能是matrix,而不是list。您能否以更可重复的方式共享您的数据?dput(head(List))和dput(df[1:10, ])可以复制/粘贴并包含所有类和结构信息 - 如果您在问题中包含这些输出,它将更容易为您提供帮助。 -
我现在添加了一个有代表性的数据集。
-
@GregorThomas 我已经添加了
df和List。很抱歉最初的混乱,很难粘贴列表。为回答您的问题,对象List属于list类。> class(List) [1] "list" -
我很惊讶你说
dplyr方法有效,当我在你的数据上尝试它时出现“递归索引”错误。