5

このデータフレームから開始

myDF = structure(list(Value = c(-2, -1, 0, 1, 2)), .Names = "Value", row.names = c(NA, 5L), class = "data.frame")

myDF$Valueのすべての行でこの関数を実行するとします。

getNumberInfo <- function(x) {
if(x %% 2 ==0) evenness = "Even" else evenness="Odd"
if(x > 0) positivity = "Positive" else positivity = "NonPositive"
if (positivity == "Positive") logX = log(x) else logX=NA
c(evenness,positivity,logX)
} 

...このデータフレームを取得するには

structure(list(Value = c(-2, -1, 0, 1, 2), Evenness = c("Even", 
"Odd", "Even", "Odd", "Even"), Positivity = c("NonPositive", 
"NonPositive", "NonPositive", "Positive", "Positive"), Log = c(NA, 
NA, NA, "0", "0.693147180559945")), row.names = c(NA, 5L), .Names = c("Value", 
"Evenness", "Positivity", "Log"), class = "data.frame")
4

3 に答える 3

8

getNumberInfo値が異なるタイプを持つことができるように、ベクトルではなくリストを返すように関数を変更したい場合があります。現状では、それらはすべて文字列にキャストされていますが、これはおそらくあなたが望むものではありませんlogX

getNumberInfo <- function(x) {
  if(x %% 2 ==0) evenness = "Even" else evenness="Odd"
  if(x > 0) positivity = "Positive" else positivity = "NonPositive"
  if (positivity == "Positive") logX = log(x) else logX=NA
  list(evenness,positivity,logX)
}

さらに、名前をいくらか効果的に使用して、繰り返す必要がないようにすることができます。

getNumberInfo <- function(x) {
  list(evenness = if(x %% 2 ==0) "Even" else "Odd",
       positivity = if(x > 0) "Positive" else "NonPositive",
       logX = if(x > 0) log(x) else NA)
}

次に、解決策は単純になります。

> cbind(myDF, t(sapply(myDF$Value, getNumberInfo)))
  Value evenness  positivity      logX
1    -2     Even NonPositive        NA
2    -1      Odd NonPositive        NA
3     0     Even NonPositive        NA
4     1      Odd    Positive         0
5     2     Even    Positive 0.6931472

最後に、ifelseの代わりに(ベクトルで機能する)を使用すると、 :ifを呼び出す必要がないため、さらに簡単になります。apply

getNumberInfo <- function(x) {
  list(evenness = ifelse(x %% 2 ==0, "Even", "Odd"),
       positivity = ifelse(x > 0, "Positive", "NonPositive"),
       logX = ifelse(x > 0, log(x), NA))
}

> cbind(myDF, getNumberInfo(myDF$Value))
  Value evenness  positivity      logX
1    -2     Even NonPositive        NA
2    -1      Odd NonPositive        NA
3     0     Even NonPositive        NA
4     1      Odd    Positive 0.0000000
5     2     Even    Positive 0.6931472

この最後のソリューションは警告を発します。これは、が含まれている要素だけでなく、すべての要素のログを実際に計算しているためx>0です。それに対処するための最もエレガントな方法がわかりません。

于 2009-09-08T19:00:13.650 に答える
3

どうですか:

 out <- cbind(myDF, t(apply(myDF, 1, getNumberInfo)))
 colnames(out) <- c('Value', 'Evenness', 'Positivity', 'Log')

それはあなたに与えます:

  値の均一性陽性ログ
1-2非陽性NAでも
2-1奇数の非正のNA
30非陽性NAでも
41奇数正0
52偶数正0.693147180559945

于 2009-09-08T17:38:51.413 に答える
3

別の選択肢:

> library(plyr)
> df <- mdply(myDF, getNumberInfo)
> names(df) <- c('Value', 'Evenness', 'Positivity', 'Log')
> df
  Value Evenness  Positivity       Log
1    -2     Even NonPositive        NA
2    -1      Odd NonPositive        NA
3     0     Even NonPositive        NA
4     1      Odd    Positive 0.0000000
5     2     Even    Positive 0.6931472
于 2009-09-09T20:47:10.467 に答える