私は、私のデータを知るためにの一部として、大きなデータフレームの各列の最小/最大を取得しようとしています。私の最初の試みは:
apply(t,2,max,na.rm=1)
最初のいくつかの列は文字型であるため、すべてを文字ベクトルとして扱います。そのため、いくつかの数値列の最大値は" -99.5"
。
私はこれを試しました:
sapply(t,max,na.rm=1)
しかし、それはmaxが因子にとって意味がないと文句を言います。 (lapply
は同じです。)私を混乱させているのは、apply
がmax
が因子にとって完全に意味があると思ったことです。列1に対して「ZEBRA」を返しました。
ところで、私は POSIXctのベクトルでsapplyを使用 を見て、答えの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
の単なるラッパーなので、両方が同じエラーを生成することは驚くことではありません。
データフレームを作成するときのデフォルトの動作では、カテゴリー列はfactorsとして保存されます。 orderedファクターであると指定しない限り、Rはを作成したと仮定しているため、max
やmin
などの演算は未定義になります。順序なしファクター。
セッション全体のデフォルトを変更するoptions(stringsAsFactors = FALSE)
を指定してこの動作を変更するか、data.frame()
構築呼び出し自体にstringsAsFactors = FALSE
を渡すことができます。これは、min
およびmax
がデフォルトで「アルファベット順」の順序を想定することを意味することに注意してください。
または、各要素の順序を手動で指定することもできますが、それがあなたのやりたいことだとは思いません。
とにかく、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)
は、数値列の最小、1分位、中央値と平均、3分位と最大、および因子列の最上位レベルの頻度を提供します。
@ltamarの答えに基づいて:
サマリーを使用して、出力を有用なものに変更します。
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からのソリューション。各列にmaxを適用するために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)
これを行うための絶対的な最良の方法は、データフレーム全体を配列に強制するbase * apply関数を避け、 colwise
fromplyr。 (誰もこれに言及していないことに驚いています)
parse_guess
をあらゆる種類のベクトルデータ型で動作する関数として使用する例:
colwise(parse_guess)(t)
あまりおもしろくない答え:forループを使用して各列に適用できます。
for (i in 1:nrow(t)) { t[, i] <- parse_guess(t[, i]) }
データフレーム構造を保持しながら* applyで割り当てを行う の良い方法がわかりません。