2017-11-06 7 views
1

条件が満たされた場合、値を別のものに置き換えることが問題になります。私は私自身の関数data_manipを使用して、必要に応じて他の条件を割り当てたり追加したりすることができます。グループ化されたデータの値をユーザー定義関数に置き換える

ただし、このdata_manip関数を使用しようとすると、割り当てられた値でそのグループ内のすべての値が変更されます。しかし、その特定のグループの他の値はこの条件を満たしていません。ここで

df <- data.frame(percent = c(0.6, 0.7,1, 0.5,0.5,1,0.4,0.6,1), 
       type = rep(c("good", "bad","ugly"),each=3), smoke=rep(c('Visky','Wine','Wine'),3), 
       sex=rep(c('male','male','female'),3)) 

> df 
    percent type smoke sex 
1  0.6 good Visky male 
2  0.7 good Wine male 
3  1.0 good Wine female 
4  0.5 bad Visky male 
5  0.5 bad Wine male 
6  1.0 bad Wine female 
7  0.4 ugly Visky male 
8  0.6 ugly Wine male 
9  1.0 ugly Wine female 


data_manip <- function(x,gr){ 
    if(grepl('goo|ug',gr)&&x<1){ 
    x[x==0.6] <- 1 
    } 
    else 
    x 
} 

df%>% 
    group_by(type)%>% 
    mutate(percent_new=data_manip(percent,type)) 

条件が彼らのためではない場合、私は、元のpercent値を保持したいと思います

# A tibble: 9 x 5 
# Groups: type [3] 
    percent type smoke sex percent_new 
    <dbl> <fctr> <fctr> <fctr>  <dbl> 
1  0.6 good Visky male   1.0 
2  0.7 good Wine male   1.0 
3  1.0 good Wine female   1.0 
4  0.5 bad Visky male   0.5 
5  0.5 bad Wine male   0.5 
6  1.0 bad Wine female   1.0 
7  0.4 ugly Visky male   1.0 
8  0.6 ugly Wine male   1.0 
9  1.0 ugly Wine female   1.0 

を与え、私が試したものです。それはif (cond) { ... } else { ... }を使用するよう

の予想される出力

# A tibble: 9 x 5 
    # Groups: type [3] 
     percent type smoke sex percent_new 
     <dbl> <fctr> <fctr> <fctr>  <dbl> 
    1  0.6 good Visky male   1.0 
    2  0.7 good Wine male   0.7 
    3  1.0 good Wine female   1.0 
    4  0.5 bad Visky male   0.5 
    5  0.5 bad Wine male   0.5 
    6  1.0 bad Wine female   1.0 
    7  0.4 ugly Visky male   0.4 
    8  0.6 ugly Wine male   1.0 
    9  1.0 ugly Wine female   1.0 
+0

試して 'ifelse()は'に '変異する()'、 'ifelse()は'ベクトル化機能です。 – fhlgood

+0

またはmutate()で 'sapply()'を使用すると、ベクトル化された出力を返すものは、mutateで新しい値を置換または作成するために使用できます。 – fhlgood

+0

@fhlgood 'sapply'と同じ結果が得られました;( – Alexander

答えて

2

は、あなたの現在のdata_manip機能は、一般的に単一の値のみをチェックし、おそらくベクトルの最初の要素をデフォルトされた、ベクトル化されていないようです。あなたの関数のベクトル化バージョンは、次のようになります。

data_manip <- function(x,gr){ 
    ifelse(grepl('goo|ug', gr) & x == 0.6, 1, x) 
} 

と期待される結果が得られます

> df%>% 
+  group_by(type)%>% 
+  mutate(percent_new=data_manip(percent,type)) 
# A tibble: 9 x 5 
# Groups: type [3] 
    percent type smoke sex percent_new 
    <dbl> <fctr> <fctr> <fctr>  <dbl> 
1  0.6 good Visky male   1.0 
2  0.7 good Wine male   0.7 
3  1.0 good Wine female   1.0 
4  0.5 bad Visky male   0.5 
5  0.5 bad Wine male   0.5 
6  1.0 bad Wine female   1.0 
7  0.4 ugly Visky male   0.4 
8  0.6 ugly Wine male   1.0 
9  1.0 ugly Wine female   1.0 

使用ifelseは、ベクトル化条件のチェックを得るために。

+0

本当にあなたの解決策と説明を感謝します!ありがとう! – Alexander

2

これはcase_whenが役に立ちそうです。

はこれを試してみてください:

library(tidyverse) 

df %>% 
    mutate(new_percentage = case_when(type == "good" & percent == 0.6 ~ 1, 
            type == "ugly" & percent == 0.6 ~ 1, 
            TRUE ~ as.double(.$percent))) 

与える:

# A tibble: 9 x 5 
    percent type smoke sex new_percentage 
    <dbl> <fctr> <fctr> <fctr>   <dbl> 
1  0.6 good Visky male   1.0 
2  0.7 good Wine male   0.7 
3  1.0 good Wine female   1.0 
4  0.5 bad Visky male   0.5 
5  0.5 bad Wine male   0.5 
6  1.0 bad Wine female   1.0 
7  0.4 ugly Visky male   0.4 
8  0.6 ugly Wine male   1.0 
9  1.0 ugly Wine female   1.0 
関連する問題