R 基于匹配字符串返回值,然后扩展到同一组中的其他行
我有一个11000行的数据集,格式如下:R 基于匹配字符串返回值,然后扩展到同一组中的其他行,r,R,我有一个11000行的数据集,格式如下: Case Type A x A y A z B a B b B z …其中大小写和类型都是多字母字符串。我想为包含Type==x或y的行添加一个新的虚拟列,我可以使用以下代码行轻松地完成此操作: df$quality <- ifelse(grepl("x|y", df$type), 1, 0) 有相当多的线程如何做到这一点。然而,我找不到任何解释如何跨组扩展返
Case Type
A x
A y
A z
B a
B b
B z
…其中大小写和类型都是多字母字符串。我想为包含Type==x或y的行添加一个新的虚拟列,我可以使用以下代码行轻松地完成此操作:
df$quality <- ifelse(grepl("x|y", df$type), 1, 0)
有相当多的线程如何做到这一点。然而,我找不到任何解释如何跨组扩展返回值的方法。具体来说,如果给定情况下的任何观察值包含x或y,我希望Quality==1。结果应该如下所示:
Case Type Quality
A x 1
A y 1
A z 1
B a 0
B b 0
B z 0
…这样,第3行也被编码为Quality==1,即使它不包含类型x或y,因为案例A中的另一行包含类型x或y。答案一定很简单,但如果能得到一些帮助,我将不胜感激 与@Psidom的思想类似,我们可以使用base R方法
ave
df$Quality <- as.numeric(as.logical(ave(df$Type, df$Case, FUN = function(i)
any(grepl("x|y", i)))))
# Case Type Quality
#1 A x 1
#2 A y 1
#3 A z 1
#4 B a 0
#5 B b 0
#6 B z 0
df$Quality与@Psidom的思想类似,我们可以使用base R方法ave
df$Quality <- as.numeric(as.logical(ave(df$Type, df$Case, FUN = function(i)
any(grepl("x|y", i)))))
# Case Type Quality
#1 A x 1
#2 A y 1
#3 A z 1
#4 B a 0
#5 B b 0
#6 B z 0
df$Quality我们可以使用data.table
。将“data.frame”转换为“data.table”(setDT(df1)
),按“Case”分组,我们通过检查元素“x”、“y”是否在%
的“Type”列中%得到逻辑向量。如果两者都需要存在,请使用all
(或者将all
替换为any
),将逻辑向量转换为二进制,使用as.integer
,并将其分配(:=
)到新列“Quality”
library(data.table)
setDT(df1)[, Quality := as.integer(all(c('x', 'y') %in% Type)), by = Case]
df1
# Case Type Quality
#1: A x 1
#2: A y 1
#3: A z 1
#4: B a 0
#5: B b 0
#6: B z 0
或者使用“OP”的方法
setDT(df1)[, Quality := as.integer(any(grepl("[xy]", Type))), by = Case]
或者对于dplyr
,我们使用与数据表中相同的方法
library(dplyr)
df1 %>%
group_by(Case) %>%
mutate(Quality = as.integer(all(c('x', 'y') %in% Type)))
#mutate(Quality = as.integer(any(c('x', 'y') %in% Type)))
tbl <- with(df1, table(Case, grepl("[x|y]", Type)))[,2]
transform(df1, Quality = +(Case %in% names(tbl[tbl!=0])))
或另一个带有表的基本R
选项
library(dplyr)
df1 %>%
group_by(Case) %>%
mutate(Quality = as.integer(all(c('x', 'y') %in% Type)))
#mutate(Quality = as.integer(any(c('x', 'y') %in% Type)))
tbl <- with(df1, table(Case, grepl("[x|y]", Type)))[,2]
transform(df1, Quality = +(Case %in% names(tbl[tbl!=0])))
tbl我们可以使用data.table
。将“data.frame”转换为“data.table”(setDT(df1)
),按“Case”分组,我们通过检查元素“x”、“y”是否在%
的“Type”列中%得到逻辑向量。如果两者都需要存在,请使用all
(或者将all
替换为any
),将逻辑向量转换为二进制,使用as.integer
,并将其分配(:=
)到新列“Quality”
library(data.table)
setDT(df1)[, Quality := as.integer(all(c('x', 'y') %in% Type)), by = Case]
df1
# Case Type Quality
#1: A x 1
#2: A y 1
#3: A z 1
#4: B a 0
#5: B b 0
#6: B z 0
或者使用“OP”的方法
setDT(df1)[, Quality := as.integer(any(grepl("[xy]", Type))), by = Case]
或者对于dplyr
,我们使用与数据表中相同的方法
library(dplyr)
df1 %>%
group_by(Case) %>%
mutate(Quality = as.integer(all(c('x', 'y') %in% Type)))
#mutate(Quality = as.integer(any(c('x', 'y') %in% Type)))
tbl <- with(df1, table(Case, grepl("[x|y]", Type)))[,2]
transform(df1, Quality = +(Case %in% names(tbl[tbl!=0])))
或另一个带有表的基本R
选项
library(dplyr)
df1 %>%
group_by(Case) %>%
mutate(Quality = as.integer(all(c('x', 'y') %in% Type)))
#mutate(Quality = as.integer(any(c('x', 'y') %in% Type)))
tbl <- with(df1, table(Case, grepl("[x|y]", Type)))[,2]
transform(df1, Quality = +(Case %in% names(tbl[tbl!=0])))
tbl您可以使用任意值为每个组创建标量值df%>%groupby(Case,Type)%>%mutate(Quality=any(grepl(“x | y”,Type)))
并将该值分配给变量,然后该值将在组内广播。您可以使用any为每个组创建标量值df%>%group_by(Case,Type)%%>%mutate(Quality=any(grepl(“x | y”,Type))
并将值分配给变量,然后它将在组内广播。收缩-as.numeric(ave(grepl([xy]”,dat$Type),dat$Case,FUN=any))
甚至ave(grepl([xy]”,dat$Type),dat$Case,FUN=any)+0
如果您想滥用类的强制。我很难理解为什么ave()在这里工作。如果在给定的案例组中,“z”行的数量远远超过“x”行和“y”行,那么它也会起作用吗?@beddotcom是的,它会!只有一个x
或一个y
就足以获得整个组中的所有1。如果您想滥用类的强制,可以将压缩为.numeric(ave(grepl([xy]”,dat$Type),dat$Case,FUN=any))
甚至ave(grepl([xy]”,dat$Type),dat$Case,FUN=any)+0。我很难理解ave()为什么在这里工作。如果在给定的案例组中,“z”行的数量远远超过“x”行和“y”行,那么它也会起作用吗?@beddotcom是的,它会!只有一个x
或一个y
就足以获得整个组的所有1。非常透明,而且有很多不同的选项。谢谢非常透明,有很多不同的选择。谢谢