bugfix> r > 投稿

データフレームに新しい変数を追加する関数を作成します。その新しい変数は、(文字列のベクトルとして)引数で渡された変数のセットに対応する値の連結で構成されます。ベースRでは、次のように記述します。

addConcatFields<-function(data,listOfVar)
{
data$uniqueId=data[,listOfVar[1]]
for(elt in listOfVar[2:length(listOfVar)])
{
data$uniqueId=paste(data$uniqueId,data[,elt],sep='_')
}
return(data)
}
addConcatFields(iris,c('Petal.Width','Species'))
# gives:
      Sepal.Length Sepal.Width Petal.Length Petal.Width Species   uniqueId
1          5.1         3.5          1.4         0.2  setosa 0.2_setosa
2          4.9         3.0          1.4         0.2  setosa 0.2_setosa
...

私の最初の目標は、dplyr :: mutateを使用して、プログラミングビネットを読んだにもかかわらずhttp://127.0.0.1:31671/library/dplyr/doc/programming.html、私は目標を達成することができませんでした。私が見逃した点を理解したいので、mutateを使用して問題を解決したいと思います。提案を感謝します。

回答 5 件
  • これに取り組む最善の方法は、準引用を使用することです。この記事は、基本を説明するのに非常に役立ちます。

    https://dplyr.tidyverse.org/articles/programming.html

    列名を文字列として保存するのではなく、最良のオプションは引用符付き文字列として保存することです。したがって、

    varlist <- rlang::quos('Petal.Width', 'Species')
    
    

    その行には、2つのクォータのリストが表示されます。1つはPetal.Widthの列を含み、もう1つはSpeciesの列です。

    その後、使用したい!!! dplyrステートメントにquosuresのリストを追加します(複数の命令をスプライシングしているため!!!)。

    dplyr::select(iris, !!! varlist)
    
    

    望ましい結果が得られるはずです。

  • データテーブルを使用して、私はこのようなことをします

    library(data.table)
    iris <- data.table(iris)
    iris[, uniqueId := do.call(function(...) paste(..., sep = "_"),.SD), .SDcols = c('Petal.Width','Species')]
    
    

  • unite をご覧ください   tidyr の関数  ここに。それは tidyverse の一部です   dplyr と同じパッケージのグループ  に含まれています。

    library(tidyr)
    unite(iris,uniqueID,c(Petal.Width,Species))
    #    Sepal.Length Sepal.Width Petal.Length       uniqueID
    #1            5.1         3.5          1.4     0.2_setosa
    #2            4.9         3.0          1.4     0.2_setosa
    #3            4.7         3.2          1.3     0.2_setosa
    #4            4.6         3.1          1.5     0.2_setosa
    
    

    連結した2つの列を失いたくない場合は、 remove = F を含めるだけです

    unite(iris,uniqueID,c(Petal.Width,Species),remove = F)
    #    Sepal.Length Sepal.Width Petal.Length       uniqueID Petal.Width    Species
    #1            5.1         3.5          1.4     0.2_setosa         0.2     setosa
    #2            4.9         3.0          1.4     0.2_setosa         0.2     setosa
    #3            4.7         3.2          1.3     0.2_setosa         0.2     setosa
    #4            4.6         3.1          1.5     0.2_setosa         0.2     setosa
    
    

  • 他の回答に追加するには、dplyrの mutate を使用してやりたいと言ったので 。

    ここに mutate での方法があります 、 paste を使用 :

    iris %>% mutate(uniqueId= paste(Petal.Width, Species, sep = '_'))
    # gives the following result:
         Sepal.Length Sepal.Width Petal.Length Petal.Width Species uniqueId
     1          5.1         3.5          1.4         0.2 setosa  0.2_setosa
     2          4.9         3            1.4         0.2 setosa  0.2_setosa
     3          4.7         3.2          1.3         0.2 setosa  0.2_setosa
     4          4.6         3.1          1.5         0.2 setosa  0.2_setosa
     5          5           3.6          1.4         0.2 setosa  0.2_setosa
     6          5.4         3.9          1.7         0.4 setosa  0.4_setosa
     7          4.6         3.4          1.4         0.3 setosa  0.3_setosa
     8          5           3.4          1.5         0.2 setosa  0.2_setosa
     9          4.4         2.9          1.4         0.2 setosa  0.2_setosa
    10          4.9         3.1          1.5         0.1 setosa  0.1_setosa
    ...
    
    

    関数がカスタム関数の場合、ベクトル化して使用できます。 たとえば、これは上記と同じ結果につながります。

    concat_fields<-function(var1, var2) {
      return (paste(var1, var2, sep = '_'))
    }
    v_concat_fields <- Vectorize(concat_fields)
    iris %>% mutate(v_concat_fields(Petal.Width, Species))
    
    

    mutateに入る関数はデータフレームの列に適用され、データフレームではなく型ベクトルの引数を持ちます。

  • ここで考えたことは別の解決策です。

    match関数を使用して、文字列名を列番号に変換します。

    次に、次のように列番号を使用します(例の数値ベクトルを一致の結果に置き換えます)。

    df <- tbl_df(df[c(3, 4, 7, 1, 9, 8, 5, 2, 6, 10)])
    
    

    これには、一致が見つからない値を返す場合、エラーで関数を中止できるという利点もあります。

あなたの答え