web-dev-qa-db-ja.com

rの複数の列を文字から数値形式に変換する

データフレーム内の複数の列を文字形式から数値形式に変換する最も効率的な方法は何ですか?

DFというすべての文字変数を含むデータフレームがあります。

私は次のようなことをしたいです

for (i in names(DF){
    DF$i <- as.numeric(DF$i)
}

ありがとうございました

13
ec0n0micus

試すことができます

DF <- data.frame("a" = as.character(0:5),
                 "b" = paste(0:5, ".1", sep = ""),
                 "c" = letters[1:6],
                 stringsAsFactors = FALSE)

# Check columns classes
sapply(DF, class)

#           a           b           c 
# "character" "character" "character" 

cols.num <- c("a","b")
DF[cols.num] <- sapply(DF[cols.num],as.numeric)
sapply(DF, class)

#          a           b           c 
#  "numeric"   "numeric" "character"
36
Luca Braglia

すでに整頓されたバースを使用している場合、正確な状況に応じていくつかの解決策があります。

library(dplyr)
library(magrittr)

# solution
dataset %<>% mutate_if(is.character,as.numeric)

# to test
df <- data.frame(
  x1 = c('1','2','3'),
  x2 = c('4','5','6'),
  x3 = c('1','a','b'), # vector with alpha characters
  stringsAsFactors = F)

# display starting structure
df %>% str()

すべての文字ベクトルを数値に変換します(数値でない場合は失敗する可能性があります)

df %>%
  select(-x3) %>% # this removes the alpha column if all your character columns need converted to numeric
  mutate_if(is.character,as.numeric) %>%
  str()

各列を変換できるかどうかを確認します。これは匿名関数にすることができます。 as.numericがNAを返すかどうかを確認します。また、因子を無視する文字ベクトルかどうかもチェックします。また、NAは意図的に導入され、後で確認されるため、警告も抑制されます。

numericcharacters <- function(x) {
  !any(is.na(suppressWarnings(as.numeric(x)))) & is.character(x)
}
df %>% 
  mutate_if(numericcharacters,as.numeric) %>%
  str()

特定の名前付き列を変換する場合は、mutate_atの方が適しています。

df %>% mutate_at('x1',as.numeric) %>% str()
11
ARobertson

列のインデックスを使用できます:data_set[,1:9] <- sapply(dataset[,1:9],as.character)

4
Masimi

私はそれを理解したと思う。これが私がしたことです(おそらく最もエレガントな解決策ではありません-改善する方法の提案[これを大歓迎です)

#names of columns in data frame
cols <- names(DF)
# character variables
cols.char <- c("fx_code","date")
#numeric variables
cols.num <- cols[!cols %in% cols.char]

DF.char <- DF[cols.char]
DF.num <- as.data.frame(lapply(DF[cols.num],as.numeric))
DF2 <- cbind(DF.char, DF.num)
2
ec0n0micus

私はこれが古いスレッドであることを理解していますが、関数のリクエストに似たソリューションを投稿したかったです(テーブル全体をパーセントラベルにフォーマットしようとする同様の問題に自分で走っただけです)。

変換する5文字の列を持つdfがあると仮定します。最初に、操作する列の名前を含むテーブルを作成します。

col_to_convert <- data.frame(nrow = 1:5
                            ,col = c("col1","col2","col3","col4","col5"))

for (i in 1:max(cal_to_convert$row))
  {
    colname <- col_to_convert$col[i]
    colnum <- which(colnames(df) == colname)
        for (j in 1:nrow(df))
          {
           df[j,colnum] <- as.numericdf(df[j,colnum])
          }
  }

セルごとに移動するため、これは大きなテーブルには理想的ではありませんが、仕事は完了します。

2
Mark Wagner

Hablarパッケージのconvertを使用できます。

library(dplyr)
library(hablar)

# Sample df (stolen from the solution by Luca Braglia)
df <- tibble("a" = as.character(0:5),
                 "b" = paste(0:5, ".1", sep = ""),
                 "c" = letters[1:6])

# insert variable names in num()
df %>% convert(num(a, b))

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

# A tibble: 6 x 3
      a     b c    
  <dbl> <dbl> <chr>
1    0. 0.100 a    
2    1. 1.10  b    
3    2. 2.10  c    
4    3. 3.10  d    
5    4. 4.10  e    
6    5. 5.10  f   

または、怠け者の場合、hablarのretype()に正しいデータ型を推測させます。

df %>% retype()

あなたに与えます:

# A tibble: 6 x 3
      a     b c    
  <int> <dbl> <chr>
1     0 0.100 a    
2     1 1.10  b    
3     2 2.10  c    
4     3 3.10  d    
5     4 4.10  e    
6     5 5.10  f   
1
davsjob

私のために働いたARobertsonとKenneth Wilsonからの回答に対するわずかな調整。

私の環境でlibrary(tidyverse)とlibrary(dplyr)を使用してR 3.6.0を実行します。

library(tidyverse)
library(dplyr)
> df %<>% mutate_if(is.character, as.numeric)
Error in df %<>% mutate_if(is.character, as.numeric) : 
  could not find function "%<>%"

私はいくつかの簡単な調査を行い、このメモをハドレーの「 The tidyverse style guide 」で見つけました。

Magrittrパッケージは、オブジェクトを所定の場所に変更するためのショートカットとして%<>%演算子を提供します。この演算子は避けてください。

# Good x <- x %>%
           abs() %>%    
           sort()

# Bad x %<>%   
          abs() %>%
          sort()

ソリューション

そのスタイルガイドに基づいて:

df_clean <- df %>% mutate_if(is.character, as.numeric)

実施例

> df_clean <- df %>% mutate_if(is.character, as.numeric)
Warning messages:
1: NAs introduced by coercion 
2: NAs introduced by coercion 
3: NAs introduced by coercion 
4: NAs introduced by coercion 
5: NAs introduced by coercion 
6: NAs introduced by coercion 
7: NAs introduced by coercion 
8: NAs introduced by coercion 
9: NAs introduced by coercion 
10: NAs introduced by coercion 
> df_clean
# A tibble: 3,599 x 17
   stack datetime            volume BQT90 DBT90 DRT90 DLT90 FBT90  RT90 HTML90 RFT90 RLPP90 RAT90 SRVR90 SSL90 TCP90 group
   <dbl> <dttm>               <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>
0
PvR

このような?

DF <- data.frame("a" = as.character(0:5),
             "b" = paste(0:5, ".1", sep = ""),
             "c" = paste(10:15),
             stringsAsFactors = FALSE)

DF <- apply(DF, 2, as.numeric)

「a」、「b」、「c」などのデータフレームに「実際の」文字がある場合、davsjobからの回答をお勧めします。

0
tickly potato

aRobertsonのこの例は、ここで見た中で最も効率的でした。整数を数値に変換するために使用しました。必要なように動作し、ループや長いコードは必要ありませんでした。

library(dplyr)
library(magrittr)

解決

dataset %<>% mutate_if(is.integer,as.numeric)
0
Kenneth Wilson

type.convert()

必要に応じて、データオブジェクトを論理、整数、数値、複素数、文字、または係数に変換します。

参照

0
Zuooo