2016-11-29 47 views
1

让数据帧是:一个数据帧R的条件子集

set.seed(123) 
df<-data.frame(name=sample(LETTERS,260,replace=TRUE), 
       hobby=rep(c("outdoor","indoor"),260),chess=rnorm(1:10)) 

和我将使用从DF提取条件是:

df_cond<-df %>% group_by(name,hobby) %>% 
    summarize(count=n()) %>% 
    mutate(sum.var=sum(count),sum.name=length(name)) %>% 
    filter(sum.name==2) %>% 
    mutate(min.var=min(count)) %>% 
    mutate(use=ifelse(min.var==count,"yes","no")) %>% 
    filter(grepl("yes",use)) 

我想随机提取的行从dfdf_conddf的其余部分)中的(名称,爱好,计数)组合相对应。我在结合%in%sample时遇到了一些问题。感谢您的任何线索!

编辑:例如:

head(df_cond) 
     name hobby count sum.var sum.name min.var use 
     <fctr> <fctr> <int> <int> <int> <int> <chr> 
    1  A indoor  2  6  2  2 yes 
    2  B indoor  8  16  2  8 yes 
    3  B outdoor  8  16  2  8 yes 
    4  C outdoor  6  14  2  6 yes 
    5  D indoor 10  24  2  10 yes 
    6  E outdoor  8  18  2  8 yes 

使用上述数据帧,我想随机df提取2行(=计数)与组合A +室内(ROW1) 8行与组合B +室内(第2排)从df ....等等。

结合@denrous和@Jacob的答案来获得我所需要的。像这样:如果

m2<-df_cond %>% 
    mutate(data = map2(name, hobby, function(x, y) {df %>% filter(name == x, hobby == y)})) %>% 
    ungroup() %>% 
    select(data) %>% 
    unnest() 



test<-m2 %>% 
group_by(name,hobby) %>% 
summarize(num.levels=length(unique(hobby))) %>% 
ungroup() %>% 
group_by(name) %>% 
summarize(total_levels=sum(num.levels)) %>% 
filter(total_levels>1) 

fin<-semi_join(m2,test) 

回答

3

如果我理解正确的话,你可以使用purrr达到你想要的东西:

df_cond %>% 
    mutate(data = map2(name, hobby, function(x, y) {filter(df, name == x, hobby == y)})) %>% 
    mutate(data = map2(data, count, function(x, y) sample_n(x, size = y))) 

如果你想与df相同的格式:

df_cond %>% 
    mutate(data = map2(name, hobby, function(x, y) {df %>% filter(name == x, hobby == y)})) %>% 
    mutate(data = map2(data, count, function(x, y) sample_n(x, size = y))) %>% 
    ungroup() %>% 
    select(data) %>% 
    unnest() 
+0

太棒了!需要 – thisisrg

+0

这不会让我满足我需要的,但足够接近。谢谢!稍后会发布最终解决方案。 – thisisrg

0

尚不清楚这正是你想要的,但你可能会寻找left_join:基于OP澄清

df %>% 
    left_join(df_cond, by = "name") 
+0

我并不想要加入。我想要从df中随机抽样(在'df_cond'中由'count'和组合名称+ hobby定义的行数]。我将添加一个示例来澄清问题。 – thisisrg

1

编辑。

必须有更好的办法,但我会使用一个循环:

library(dplyr) 

master_df <- data.frame() 

for (i in 1:nrow(df_cond)){ 
    name = as.character(df_cond[i, 1]) 
    hobby = as.character(df_cond[i, 2]) 
    n = as.numeric(df_cond[i, 3]) 

    temp_df <- df %>% filter(name == name, hobby == hobby) 
    temp_df <- sample_n(temp_df, n) 
    master_df <- rbind(master_df, temp_df) 
     } 
+0

谢谢......但这不完全是我我试图澄清这个问题 – thisisrg

+0

我可以看到如何工作的原理,但它没有给出正确的输出结果我已经结合你的和@denrous的答案来得到我需要的东西 – thisisrg