各列を観察するデータフレームの各列に関数を適用します既存のデータ型

StackOverflow https://stackoverflow.com/questions/7303322

  •  25-10-2019
  •  | 
  •  

質問

の一部として、大きなデータフレームで各列のmin/maxを取得しようとしています 私のデータを知る. 。私の最初の試みは:

apply(t,2,max,na.rm=1)

最初のいくつかの列は文字タイプであるため、すべてを文字ベクトルとして扱います。したがって、いくつかの数値列の最大は次のように出てきています " -99.5".

それから私はこれを試しました:

sapply(t,max,na.rm=1)

しかし、それは不平を言っています マックスは要因にとって意味がありません. (lapply 同じです。)私を混乱させているのはそれです apply 考え max 要因にとって完全に意味がありました。たとえば、列1の「ゼブラ」を返しました。

ところで、私は見ました posixctのベクトルでサプライを使用します そして答えの1つは言います」Sapplyを使用すると、オブジェクトは数値に強制されています..."。これは私に何が起こっているのか?もしそうなら、強制しない代替の適用関数はありますか?確かにそれは一般的なニーズです。データフレームタイプの重要な機能の1つは、各列が異なる可能性があることですタイプ。

役に立ちましたか?

解決

それが「秩序化された要因」であれば、物事は異なるでしょう。 「秩序ある要因」が好きだということではなく、「要因」に対して定義されていない「秩序化された要因」に対していくつかの関係が定義されていると言うだけではありません。要因は、通常のカテゴリ変数と考えられています。あなたはあなたのロケールのアルファベットの語彙順である要因の自然な順序を見ています。すべての列、...日付と要因などの「数値」に自動強制を取得したい場合は、次のことを試してください。

sapply(df, function(x) max(as.numeric(x)) )   # not generally a useful result

または、最初に要因をテストし、予想どおりに戻ってくる場合は:

sapply( df, function(x) if("factor" %in% class(x) ) { 
            max(as.numeric(as.character(x)))
            } else { max(x) } )

@darrensコメントはうまく機能します:

 sapply(df, function(x) max(as.character(x)) )  

max 文字ベクトルで成功します。

他のヒント

その理由 max で動作します apply それです apply データフレームを最初にマトリックスに強制し、マトリックスは1つのデータ型のみを保持できます。したがって、文字のマトリックスになります。 sapply ただのラッパーです lapply, 、そのため、両方が同じエラーを生成することは驚くことではありません。

データフレームを作成するときのデフォルトの動作は、カテゴリの列をとして保存するためのものです 要因. 。あなたがそれがであることを指定しない限り 順序付けられました 要因、ような操作 maxmin Rが作成したと仮定しているため、未定義になります。 順序付けられていません 要素。

この動作を指定することで変更できます options(stringsAsFactors = FALSE), 、セッション全体のデフォルトを変更するか、合格することができます stringsAsFactors = FALSE の中に data.frame() 建設はそれ自体を呼び出します。これはそれを意味することに注意してください minmax デフォルトで「アルファベット順」順序を想定します。

または、各要因の順序を手動で指定することもできますが、それがあなたがやりたいことだとは思いません。

関係なく、 sapply 一般に、原子ベクトルが生成され、多くの場合、すべてを文字に変換することが伴います。これを回避する1つの方法は次のとおりです。

#Some test data
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

d[4,] <- NA

#Similar function to DWin's answer          
fun <- function(x){
    if(is.numeric(x)){max(x,na.rm = 1)}
    else{max(as.character(x),na.rm=1)}
}   

#Use colwise from plyr package
colwise(fun)(d)
         v1 v2       v3 v4
1 0.8478983  j 1.999435  J

データを学びたい場合 summary (df) Min、1番目の分位、中央値と平均、数値柱の3番目の分位と最大、および因子列の最上位レベルの周波数を提供します。

@ltamarの回答に基づいて構築:
概要を使用して、出力を有用なものにMunge!

library(tidyr)
library(dplyr)

df %>% 
  summary %>% 
  data.frame %>%
  select(-Var1) %>%
  separate(data=.,col=Freq,into = c('metric','value'),sep = ':') %>%
  rename(column_name=Var2) %>%
  mutate(value=as.numeric(value),
         metric = trimws(metric,'both') 
  ) %>%  
  filter(!is.na(value)) -> metrics

それはきれいではなく、確かに高速ではありませんが、仕事を終わらせます!

使用するソリューション retype() Hablarから強制因子、不安定性に応じて文字または数値タイプまで。私は使用します dplyr 各列に最大を適用するため。

コード

library(dplyr)
library(hablar)

# Retype() simplifies each columns type, e.g. always removes factors
d <- d %>% retype()

# Check max for each column
d %>% summarise_all(max)

結果

新しい列タイプではありません。

     v1 v2       v3 v4   
  <dbl> <chr> <dbl> <chr>
1 0.974 j      1.09 J   

データ

# Sample data borrowed from @joran
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

これを行うための絶対的な最良の方法は、ベース *の適用関数を回避することです。これは、データフレーム全体を配列に強制し、使用します colwise から Plyr. 。 (誰もこれについて言及していないことに驚いています)

使用の例 parse_guess あらゆる種類のベクトルデータ型で動作する関数として:

colwise(parse_guess)(t)

あまり興味深い答え:ループを使用して各列に適用できます。

for (i in 1:nrow(t)) { t[, i] <- parse_guess(t[, i]) }

私は良い方法を知りません データフレーム構造の保存中に *適用される *で割り当てを行う.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top