2017-10-21 3 views
-1

私は、特定のデータフレームに対して、関数の最初の引数として列名を使用でき、列の値(特定の列の行値)を関数の第2引数。 2番目の引数の値は、スイッチ関数で設定された値に基づいて数値に変換されます。Rでapply関数を使用するには関数の引数の列名と値が同じ列に必要ですか?

ここまで私がこれまで取り組んできたことは次のとおりです。ここで

# I also put print("ERROR in Question")) if there is no match at all 
scoreraw <- function(Question, Answer) { 

    switch(Question, "Today is my favourite day?" = 
    {switch(Answer,"Strongly Agree" = 3,"Agree"= 2, "Disagree" = 1, "Strongly 
Disagree" = 0)}, 
    "I hate Tuesdays?"= 
    {switch(Answer,"Strongly Agree" = 0,"Agree"= 1, "Disagree" = 2, "Strongly 
Disagree" = 3)}, 
    print("ERROR in Question")) 
} 

、それがどのように機能するかを実証するための機能を備えた簡単なテストです:

# We expect the value to be 3 based on the Question and Answer argument 
scoreraw("Today is my favourite day?","Strongly Agree") 
    # [1] 3 



#Let us now create a dummy dataset of questions 

x <- c("Strongly Agree","Agree","Disagree","Strongly Disagree") 
y <- c("Strongly Agree","Agree","Disagree","Strongly Disagree") 

c <- data.frame(x,y) 

# Just changing the names to match the questions in the switch statement 
colnames(c) <- c("Today is my favourite day?", "I hate Tuesdays?") 

# The two factors were converted to characters since factors are treated as 
# integers by default (I may be incorrect here) 
c$`Today is my favourite day?` <- as.character(c$`Today is my favourite day`) 
c$`I hate Tuesdays?` <- as.character(c$`I hate Tuesdays`) 

#>c 
# Today is my favourite day? I hate Tuesdays? 
# 1    Strongly Agree Strongly Agree 
# 2      Agree    Agree 
# 3     Disagree   Disagree 
# 4   Strongly Disagree Strongly Disagree 

これは私がデータフレームは私が

# Today is my favourite day? I hate Tuesdays? 
# 1       3    0 
# 2       2    1 
# 3       1    2 
# 4       0    3 

私の関数を適用した後のように見てみたいものです適用関数を使用しようとしましたが、問題は任意の列名を選択し、特定の列のすべての行の値に関数を適用する方法です。 。私は瞬間私は手動でカラム名と特定の行の値を選択して関数を適用することができます。能力のない

#Example of selecting column name and row value manually 
scoreraw(colnames(c)[2],c[1,2]) 
# [1] 0 

EDIT現在の作業コードは、私が今、どの列/ sまでscoreraw関数を適用するcall_scoreraw機能でループのために組み込むしようとしている任意の列

# I also put print("ERROR in Question")) if there is no match at all 
scoreraw <- function(Question, Answer) { 

    switch(Question, "Today is my favourite day?" = 
    {switch(Answer,"Strongly Agree" = 3,"Agree"= 2, "Disagree" = 1, "Strongly 
Disagree" = 0)}, 
    "I hate Tuesdays?"= 
    {switch(Answer,"Strongly Agree" = 0,"Agree"= 1, "Disagree" = 2, "Strongly 
Disagree" = 3)}, 
    print("ERROR in Question")) 
} 


#Let us now create a dummy dataset of questions 

x <- c("Strongly Agree","Agree","Disagree","Strongly Disagree") 
y <- c("Strongly Agree","Agree","Disagree","Strongly Disagree") 

c <- data.frame(x,y) 

# Just changing the names to match the questions in the switch statement 
colnames(c) <- c("Today is my favourite day?", "I hate Tuesdays?") 

# The two factors were converted to characters since factors are treated as 
# integers by default (I may be incorrect here) 
c$`Today is my favourite day?` <- as.character(c$`Today is my favourite 
day`) 
c$`I hate Tuesdays?` <- as.character(c$`I hate Tuesdays`) 



call_scoreraw <- function(n, DF) { 
    sapply(DF[[n]], function(x) scoreraw(colnames(DF)[n], x)) 
} 

#I included unlist as I noticed the output can also be a list 
a <- unlist(call_scoreraw(1, c)) 
b <- as.data.frame(a) 

を選択します。

call_scoreraw <- function(n, DF) { 
    Storage <- numeric(ncol(DF)) 
    for (i in n:ncol(DF)){ 
    Storage[i] <- sapply(DF[,i], function(x) scoreraw(colnames(DF)[i], x)) 
    } 
} 

ご覧のとおり、私は現在forループの値を格納する方法を見つける必要があります。私は定義されたストレージ変数Storageを使用してこれを行うことができませんどのように私はこれを行うことができますか?

+0

「scoreraw」関数にタイプミスがあります。「火曜日」ではなく、「tuesdays」でなければなりません。 –

+0

ありがとう私は今、誤植を変更しました。 @RuiBarradas – MrReference

答えて

0

scorerawを呼び出す別の関数を定義します。このように:

call_scoreraw <- function(n, DF) { 
    if(length(n) > 1){ 
     t(sapply(n, function(i){ 
      sapply(DF[[i]], function(x) scoreraw(colnames(DF)[i], x)) 
     })) 
    } else { 
     sapply(DF[[n]], function(x) scoreraw(colnames(DF)[n], x)) 
    } 
} 

call_scoreraw(2, c) 
# Strongly Agree    Agree   Disagree Strongly Disagree 
#    0     1     2     3 

call_scoreraw(1:2, c) 
#  Strongly Agree Agree Disagree Strongly Disagree 
#[1,]    3  2  1     0 
#[2,]    0  1  2     3 

なお、あなたがしたい場合は、data.frameに強制することができ、クラスmatrixのオブジェクトを返しますn値のベクトルとのコール。

res <- call_scoreraw(1:2, c) 
res2 <- as.data.frame(res) 
+0

このcall_scoreraw関数を任意の数の列に適用するとどうでしょうか? - この機能を自動化して、選択したい列を手動で索引付けする必要はありません。つまり暗黙のFORループです。 @RuiBarradas – MrReference

+0

コードを試してみましたが、うまくいきました。私の学習のために、あなたはおそらくこのコードの部分を説明できますか?(サプリー(n、function(i){ sapply(DF [[i])、function(x)scoreraw(colnames(DF)[i] '' function(i) '' function(i){ sapply(DF [[i])内に2番目の '' appapply'関数を埋め込む理由を理解したいと思います。 – MrReference

+0

@MrReference最初の 'sapply'はベクトル' n'をループし、2番目の 'sapply'はベクトル' DF []を介してループします。 [i]] '。したがって、 'n 'の各' i'と 'DF [[i]]'の各 'x'は' scoreraw'関数を適用し、カラム名とスカラーという2つの引数をとります。 –

関連する問題