2013-06-13 1 views
0

다음 문제에 대한 벡터화 된 해결책을 찾기 위해 고심하고 있습니다. 나는 사람들이 허용 된 직업을 모든 사람을 확인하고, 그렇지 않은 어떤 이름을 반환하고자한다하나의 데이터 프레임에있는 값이 다른 (더 큰) 데이터 프레임에 있는지 확인하십시오.

> people <- data.frame(name = c('Fred', 'Bob'), profession = c('Builder', 'Baker')) 
> people 
    name profession 
1 Fred Builder 
2 Bob  Baker 

> allowed <- data.frame(name = c('Fred', 'Fred', 'Bob', 'Bob'), profession = c('Builder', 'Baker', 'Barman', 'Biker')) 
> allowed 
    name profession 
1 Fred Builder 
2 Fred  Baker 
3 Bob  Barman 
4 Bob  Biker 

말할 : 나는 두 dataframes 있습니다.

예를 들어, Fred는 Builder 또는 베이커 일 수 있습니다. 따라서 그는 괜찮습니다. 그러나 Bob은 Barman이나 Biker가 될 수 있지만 Baker가 될 수는 없습니다 (참고 : 사용 사례에는 두 가지만 허용되는 직업이 있습니다).

나는 데이터 프레임을 반환에 허용 된 직업이없는 그 이름을 싶습니다 도움

+0

허용되는 직업이없는 이름을 원하십니까? –

+0

예 - 모든 이름에 허가 된 직업이 있는지 확인하고 그렇지 않은 이름을 반환하고 싶습니다. 명확성을 위해 무효 업데이트 – rwb

답변

1

간단한 기본 전용 솔루션에 대한

name profession permitted 
1 Bob Baker Biker 
2 Bob Baker Barman 

감사합니다. 나는 누군가가 뭔가 더 잘할 수 있다고 확신합니다.

out <- allowed[!allowed$name %in% merge(people, allowed)$name, ] 

이것은 허용 된 직업과 함께 원하는 사람을 얻습니다. 실제 직업을 원한다면 :

names(out)[2] <- "permitted" 
out <- merge(people, out, all.y=TRUE) 
0

아마도 다른 방법이있을 수 있습니다. 그러나 이것은 효과가 있습니다. 필자는 허락되지 않은 직업을 가진 제 3의 사람을 추가하여이 기능을 전체 데이터 세트에 적용하는 방법을 보여주었습니다.

currentprof <-structure(list(name = structure(c(2L, 1L, 3L), .Label = c("Bob", 
"Fred", "Jan"), class = "factor"), profession = structure(c(3L, 
2L, 1L), .Label = c("Analyst", "Baker", "Builder"), class = "factor")), .Names = c("name", 
"profession"), class = "data.frame", row.names = c(NA, -3L)) 

allowed <- structure(list(name = structure(c(2L, 2L, 1L, 1L, 3L, 3L), .Label = c("Bob", 
"Fred", "Jan"), class = "factor"), profession = structure(c(4L, 
1L, 2L, 3L, 6L, 5L), .Label = c("Baker", "Barman", "Biker", "Builder", 
"Driver", "Teacher"), class = "factor")), .Names = c("name", 
"profession"), class = "data.frame", row.names = c(NA, -6L)) 

checkprof <- function(name){ 
allowedn <- allowed[allowed$name == name,] 
currentprofn <- currentprof[currentprof$name==name,] 
if(!currentprofn$profession %in% allowedn$profession) 
{result <- merge(currentprofn, allowedn, by = "name", all.x=TRUE)} else 
{result <-data.frame(col1=character(), 
       col2=character(), 
       col3=character(), 
       stringsAsFactors=FALSE)} 
colnames(result) <- c("name","profession","permitted") 
return(result) 
} 


do.call(rbind,lapply(levels(allowed$name),checkprof)) 
0

이것은 내 작업입니다. 그래도 더 많은 테스트가 필요할 수 있습니다. 제안 사항에 대해 공개하겠습니다. 그것은 당신의 예제와 함께 작동하지만 일반화 될지 확실하지 않습니다.

people$check <- ifelse(people$profession %in% allowed[which(allowed$name == people$name),"profession"], TRUE,FALSE) 

people_select <- people[people$check == TRUE,] 

EDIT : 이것은 투표에서 뒤로 물러나는 경우를 대비하여 설명되어 있습니다. ifelse는 벡터화되어 매우 빠르게 실행됩니다.

1

약간 더 읽기 쉬운 data.table 솔루션입니다. 읽을 수 있다고 생각할 경우, 한 줄짜리 줄을 만들기 위해 같은 줄에서 마지막 단계를 수행 할 수 있습니다.

# load library, convert people to a data.table and set a key 
library(data.table) 
people = data.table(people, key = "name,profession") 

# compute 
result = data.table(allowed, key = "name")[people[!allowed]] 
setnames(result, "profession.1", "permitted") 

result 
# name profession permitted 
#1: Bob  Barman  Baker 
#2: Bob  Biker  Baker 
관련 문제