8224


csvファイルを読み込んで平均などを計算して出力しようとしています。  
文字列を含んでいる３列目があるたけ、計算に失敗します。回避方法はありませんでしょうか。

（なお、文字列を含んでいる場合は、個数を数えたいです）

元ファイル  
Test1.csv

[code]

    1,2,hogehoge,3,4
    2,3,hogehoge,4,5
    4,5,,4,5
    5,6,halohalo,4,6
    
[/code]

実行するスクリプト

[code]

    my_mode <- function(x) {
    names(which.max(table(x)))
    # as.integer(names(which.max(table(x)))) 
    }
    methods <- c('mean', 'median', 'my_mode', )
    a <- read.csv("Test1.csv")
    result <- sapply(methods, function(method) {
    sapply(a, function(column) {
        do.call(method, list(column))
    })
    })
    write.csv(result, file='Stat2.csv')
    
[/code]

実行結果

[code]

     警告メッセージ: 
     In read.table(file = file, header = header, sep = sep, quote = quote,  :
     incomplete final line found by readTableHeader on 'Test1.csv'
     以下にエラー median.default(c(3L, 1L, 2L)) : need numeric data
     Calls: sapply ... lapply -> FUN -> do.call -> median -> median.default
     追加情報:  警告メッセージ: 
     In mean.default(c(3L, 1L, 2L)) :
     引数は数値でも論理値でもありません。NA 値を返します 
     実行が停止されました 
    
[/code]

期待する結果

[code]

    ,mean,median,my_mode,count
    X1,3.666666667,4,2,5
    X2,4.666666667,5,3,5
    X,NA,NA,NULL,3
    X3,4,4,4,5
    X4,5.333333333,5,5,5
    
[/code]


CC BY-SA 3.0
2015-03-19T11:45:03.960
8130
2015-03-23T17:01:35.400
2015-03-20T02:01:01.920
7590
7590
question
bash r
Rで計算する際に文字列を含んでいる列があるため計算に失敗する


median がエラーを出しているようなので、以下のようなラッパー関数を書けば回避はできます。

[code]

    my_median <- function(x) {
      ifelse(is.numeric(x), median(x), NA)
    }
    
[/code]

ただ、数値とか文字列とか型の違いによって処理の仕方が違うのなら、分けて処理する方が自然だとは思います。

[code]

    numeric_index <- sapply(a, is.numeric)
    a_numeric <- a[, numeric_index]
    a_others  <- a[, !numeric_index]
    
[/code]

回避策の方は以下のようになると思います。ちなみに、read.csv() は header = FALSE
を指定しないと一行目がヘッダとして扱われてしまうので注意してください。

[code]

    a <- read.csv("Test1.csv", header = FALSE, na.strings = "")
    
    my_mode <- function(x) {
      names(which.max(table(x)))
    }
    
    my_median <- function(x) {
      ifelse(is.numeric(x), median(x), NA)
    }
    
    my_count <- function(x) {
      sum(!(is.na(x)))
    }
    
    methods <- c(mean, my_median, my_mode, my_count)
    
    sapply(methods, function(method) {
      sapply(a, method)
    })
    
    #> Warning message:
    #> In mean.default(X[[3L]], ...) :
    #>   argument is not numeric or logical: returning NA
    #>    [,1]   [,2] [,3]       [,4]
    #> V1 "3"    "3"  "1"        "4" 
    #> V2 "4"    "4"  "2"        "4" 
    #> V3 NA     NA   "hogehoge" "3" 
    #> V4 "3.75" "4"  "4"        "4" 
    #> V5 "5"    "5"  "5"        "4" 
    
[/code]


CC BY-SA 3.0
2015-03-22T01:28:25.923
8224
2015-03-22T01:28:25.923
2544
8130
answer