2017-07-17 78 views
0

我有一個函數remove_fun,它根據某些條件從數據框中刪除行(該函數太冗長以至於不能包含,所以這裏是一個簡化示例:)。從數據框中刪除行直到滿足條件

比方說,我有一個名爲block_2數據幀,有兩列:

Treatment seq 
     1 29 
     1 23 
     3 60 
     1 6 
     2 41 
     1 5 
     2 44 

對於這個例子的目的,讓我們說我的函數的基礎上的最高值時去除block_2 1行seq在block_2$seq。此功能效果很好,當我跑了一次,即remove_fun(block_2)將返回以下輸出:

Treatment seq 
    1  29 
    1  23 
    1  6 
    2  41 
    1  5 
    2  44 

然而,什麼我沒搞清楚是如何實現重複我remove_fun,直到我減少block_2到一定尺寸。

我的想法是做這樣的事情:

while (dim(block_2_df)[1]>1)#The number of rows of block_2_df{ 
    remove_fun(block_2_df) 
} 

這在理論上減少block_2_df直到僅對應於最低序列號的觀測仍然存在。

但是,這不起作用。我認爲我的問題與我有關,不知道如何反覆使用我的'更新'block_2_df。我想做到的是一些代碼,做這樣的事情:

new_df_1<-remove_fun(block_2) 
new_df_2<-remove_fun(new_df_1) 
new_df_3<-remove_fun(new_df_2) 

等等

我不一定要找一個確切的解決這個問題(因爲我沒有提供remove_fun),但我會很感激一些見解:解決問題的一般方法。

編輯:這是我的一些示例數據實際代碼:

#Start from a block of 10*6 balls, with lambda*(wj) balls of each class 
#Allocation ratios 
class_1<-"a" 
class_2<-"b" 
class_3<-"c" 

ratio_a<-3 
ratio_b<-2 
ratio_c<-1 
#Min_set 
min_set<-c(rep(class_1,ratio_a),rep(class_2,ratio_b),rep(class_3,ratio_c)) 
min_set_num<-ifelse(min_set=='a',1,ifelse(min_set=='b',2,3)) 

table_key <- table(min_set_num) 

#Number of min_sets 
lamb<-10 
#Active urn 
block_1<-matrix(0,lamb,length(min_set)) 
for (i in 1:lamb){ 
    block_1[i,]<-min_set 
} 

#Turn classes into a vector 
block_1<-as.vector(block_1) 
block_1<-ifelse(block_1=='a',1,ifelse(block_1=='b',2,3)) 
#Turn into a df w/ identifying numbers: 
block_1_df<-data.frame(block_1,seq(1:length(block_1))) 
#Enumerate all sampling outcome permutations 
library('dplyr') 
#Create inactive urn 
#Sample from block_1 until min_set is achieved, store in block_2##### 
#Random sample : 
block_2<-sample(block_1,length(block_1),replace=F) 

block_2_df<-block_1_df[sample(nrow(block_1_df), length(block_1)), ] 
colnames(block_2_df)<-c('Treatment','seq') 
#Generally:#### 

remove_fun<-function(dat){ 
    #For df 
    min_set_obs_mat<-matrix(0,length(block_1),2) 
    min_set_obs_df<-as.data.frame(min_set_obs_mat) 
    colnames(min_set_obs_df)<-c('Treatment','seq') 

    for (i in 1:length(block_1)){ 
    if ((sum(min_set_obs_df[,1]==1)<3) || (sum(min_set_obs_df[,1]==2)<2) || (sum(min_set_obs_df[,1]==3)<1)){ 
     min_set_obs_df[i,]<-dat[i,] 
    } 
    } 
    #Get rid of empty rows in df: 
    min_set_obs_df<-min_set_obs_df%>%filter(Treatment>0) 

    #Return the sampled 'balls' which satisfy the minimum set into block_2_df (randomized block_!), #### 
    #keeping the 'extra' balls in a new df: extra_df:#### 

    #Question: does the order of returning matter?#### 

    #Identify min_set 
    outcome_df<-min_set_obs_df %>% group_by(Treatment) %>% do({ 
    head(., coalesce(table_key[as.character(.$Treatment[1])], 0L)) 
    }) 

    #This removes extra observations 'chronologically' 
    #Identify extra balls 
    #Extra_df is the 'inactive' urn#### 
    extra_df<-min_set_obs_df%>%filter(!(min_set_obs_df$seq%in%outcome_df$seq)) 
    #Question: is the number of pts equal to the block size? (lambda*W)?###### 

    #Return min_df back to block_2_df, remove extra_df from block_2_df: 
    dat<-dat%>%filter(!(seq%in%extra_df$seq)) 

return(dat) 
} 

回答

1

您while循環不會重新定義block2_df。這應該工作:

while (dim(block_2_df)[1]>1) { 
    block_2_df <- remove_fun(block_2_df) 
} 
+0

謝謝你的提示。但是,由於某些原因,這仍然不起作用。我在原始文章中附加了我的功能的實際代碼,以查看您/任何人是否可以發現問題。 – lecreprays

+0

期望的輸出是什麼?您是否希望最終獲得具有特定數量的每個治療組的數據框? while循環對於重複應用應該很好,所以問題在於函數。 – Eldioo

0

如果你需要的是子集的數據幀的方式...

df <- data.frame(Treatment = c(1, 1, 3, 1, 2, 1, 2), 
        seq = c(29, 23, 60, 6, 41, 5, 44)) 

df 
    Treatment seq 
1   1 29 
2   1 23 
3   3 60 
4   1 6 
5   2 41 
6   1 5 
7   2 44 

# Decide how many rows you want in output 

n <- 6 

# Find the top "n" values in the seq variable 

head(sort(df$seq), n) 
[1] 5 6 23 29 41 44 


# Use them in the subset criteria 

df[df$seq %in% head(sort(df$seq), n), ] 
    Treatment seq 
1   1 29 
2   1 23 
4   1 6 
5   2 41 
6   1 5 
7   2 44 
+0

正如我在OP中提到的那樣,我實際上試圖完成一個df(任意)的減少直到某個條件。 – lecreprays

+0

在示例代碼中迭代改變'n'將會減少基於'df $ seq'最高值的數據幀,直到剩下一行爲止,seq的最低值,如示例中所述 – Damian