[英]How to get a subset of a dataframe which only has elements which appear in the set more than once in R
[英]How to subset a dataframe in r based on an observation whose cell has more than one value separated by commas?
我对R和程序设计还算陌生,所以请多多包涵。
我有一个非常大的数据集(100,000多个观测值)。 我想基于一个特定列上的值对该数据集进行子集化。 我面临的问题是,我关注的列中的各个单元格可以一次采用多个值,并以逗号分隔。 例如说我有一个数据集“ m”:
row1<-c('1','Jon,Ryan,Lilly','Soccer','3')
row2<-c('2','Carol,Ben,Peter','Soccer','6')
row3<-c('3','Ben,Carol,Billy','Soccer','5')
row4<-c('4','Felix,Jon,Casper','Soccer','3')
m<-rbind(row1,row2,row3,row4)
colnames(m)<-c('ID','Name','Event','Duration')
rownames(m)<-c(1,2,3,4)
print(m)
ID Name Event Duration
1 "1" "Jon,Ryan, Lilly" "Soccer" "3"
2 "2" "Carol, Ben, Peter" "Soccer" "6"
3 "3" "Ben, Carol, Billy" "Soccer" "5"
4 "4" "Felix, Jon, Casper" "Soccer" "3"
如何对“ m”进行子集处理,以使R仅返回“名称”列等于“ Jon”的观测值。 我试过了
subset(data, Name=='Jon')
但这只会返回“ Jon”是列出的唯一名称的字段。 我知道使用colsplit
可以从这些不同的元素创建新的列,但是某些单元格具有不同数量的列,有些单元格具有10多个元素,并且所有单元格中共有100多个不同的唯一名称。 他们在R中的命令是否可以基于名称字符串的“子集”进行子集设置? 和子集函数一样简单,但也查询字符串的一部分。 预先感谢大家的帮助!
您可以使用此代码搜索Jon并返回一个布尔值。
m.df <- as.data.frame(m)
m.df$Name <- as.character(m.df$Name)
m.df$new <- str_detect(m.df$Name, "Jon")
> m.df
ID Name Event Duration new
1 1 Jon,Ryan,Lilly Soccer 3 TRUE
2 2 Carol,Ben,Peter Soccer 6 FALSE
3 3 Ben,Carol,Billy Soccer 5 FALSE
4 4 Felix,Jon,Casper Soccer 3 TRUE
这是一种搜索多个名称列的技巧。 合并要搜索的列,然后在组合列上使用相同的代码。
假设您还有另一列NameName-
m.df$combo <- paste(m.df$Name, m.df$NameTwo, sep = ",")
m.df$new <- str_detect(m.df$combo, "Jon")
在名称列表中放置搜索的名称有4种不同的可能性:
因此,如果您在任何特定位置,都可以将grepl
与匹配名称的匹配字符串一起使用:
Name <- c("Jon,Ryan, Lilly",
"Carol, Ben, Peter",
"Ben, Carol, Billy",
"Felix, Jon, Casper")
grepl('(^\\s*Jon,)|(,\\s*Jon,)|(,\\s*Jon\\s*$)|(^\\s*Jon\\s*$)',Name)
#> [1] TRUE FALSE FALSE TRUE
您可以这样概括:
includesName <- function(name,x)
grepl(paste0('(^\\s*',name,',)|(,\\s*',name,',)|(,\\s*',name,'\\s*$)|(^\\s*',name,'\\s*$)'),
x)
includesName('Jon',Name)
#> [1] TRUE FALSE FALSE TRUE
\\ s的使用是为了允许在名称之间或列表的末尾包含空格(特别是如果这些数据存储在具有固定宽度字符列的数据库中,或者是手工的话)输入)。
明确匹配每个方案的原因是(而不是"(Jon$)|(Jon,)"
是要匹配全名,因此当您不是故意匹配时,不要意外匹配“ Ron Jon”。
对于dplyr来说 ,这是一项艰巨的任务,尤其是考虑到实际数据的大小。 我为您的m
创建一个tbl_df
,它基本上是一个data.frame。 自从您问了这件事以来,我包括了第二个基于名称的变量。 我创建了一个自定义函数来搜索字符串Jon
。 然后使用mutate_each()
在名称变量中进行搜索,然后对结果进行过滤以仅返回匹配的行。
library(dplyr)
library(stringr)
m <- data_frame(Name1 = c('Jon,Ryan,Lilly', 'Carol,Ben,Peter',
'Ben,Carol,Billy', 'Felix,Jon,Casper'),
Name2 = c('Susie,Jenny,Katy', 'Nigel,Ian,Jon',
'Nigel, Jenny', 'Ryan, Lilly, Ben'),
Event = 'Soccer',
Duration = c(3, 6, 5, 3))
m
# Source: local data frame [4 x 4]
# Name1 Name2 Event Duration
# 1 Jon,Ryan,Lilly Susie,Jenny,Katy Soccer 3
# 2 Carol,Ben,Peter Nigel,Ian,Jon Soccer 6
# 3 Ben,Carol,Billy Nigel, Jenny Soccer 5
# 4 Felix,Jon,Casper Ryan, Lilly, Ben Soccer 3
jon_fun <- function(x) str_detect(x, '\\bJon\\b')
m %>%
mutate_each(funs(jon_fun), jon1 = Name1, jon2 = Name2) %>%
filter(jon1 | jon2) %>%
select(-starts_with('jon'))
# Source: local data frame [3 x 4]
# Name1 Name2 Event Duration
# 1 Jon,Ryan,Lilly Susie,Jenny,Katy Soccer 3
# 2 Carol,Ben,Peter Nigel,Ian,Jon Soccer 6
# 3 Felix,Jon,Casper Ryan, Lilly, Ben Soccer 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.