2017-11-01 7 views
0

おはようございますみんな、Rで分割する列についていくつか読んだことがありますが、私の場合を修正する方法が見つかりませんでした。データフレームのいくつかの列を 'separate'(tidyr)で分割するR

セパレータに従って、tidyr Rパッケージの 'separate'関数を使用して、2つの列のデータフレームの列を分割したいと考えています。

私はこのデータフレームがあります。

dat1 AIN5997 AIN7452 AIN8674 AIN9655 001 01/02 02/02 02/02 01/02 002 01/02 01/01 02/02 02/02 003 01/02 01/02 01/01 02/02 004 01/02 01/01 02/02 01/02 005 01/01 01/01 02/02 02/02 006 01/02 01/02 01/01 02/02 ...

をそして私は、カラム名を維持しながら、可能な場合は、「/」(例えばに従って二つに各列を分離したいと思います:AIN5997になるでしょうAIN5997。 1とAIN5997.2)

私はそれは可能ですが、 '適用'を試みているときに私のフレームの各列にプロシージャを拡張できませんでした(データフレームと単一の列一度に)。これは実際には非常に簡単ですが、私のRスキルはかなり悪いです!

は、このように、二つに一つの列を分割する方法を説明する多くのスレッドがあります。Split a column of a data frame to multiple columns

が、私は、同時にいくつかの列のための手続きを拡張する方法を見つけることができません。

は、あなたの助けをありがとうございました

すべてのベスト:)トリックはあなたが発注されている分離する列を正しい順序で新しい名前を作成し、これを確認することです

+0

「別個の」またはそれに関係する解決策が必要なソリューションはありますか? – amarchin

+0

アドバイスは非常に便利です、ありがとうございましたAmarchin :-) – Chrys

答えて

0

前進。

NA値の問題は、プロセスがそれらを分割できないことです。だから、そのトリックは、あなたが分けることのできるものでそれらを置き換えることです。これを確認してください:

library(dplyr) 
library(tidyr) 

# example dataset 
dt = data.frame(id = 1:2, 
       AIN5997 = c("01/02", "01/02"), 
       AIN7452 = c("02/02", NA), 
       AIN8674 = c("02/02","02/02"), stringsAsFactors = F) 

# specify columns you want to separate (specify column positions) 
input_names = names(dt)[2:4] 

# create new names (you want each name twice) 
new_names = expand.grid(input_names, 1:2) %>% 
    unite(v, Var1, Var2, sep=".") %>% 
    pull(v) %>% 
    sort() 

dt %>% 
    unite_("v", input_names) %>%     # unite columns of interest 
    mutate(v = gsub("NA", "NA/NA", v)) %>%  # replace NAs with something that can be separated 
    separate(v, new_names, convert = F)   # separate elements and give new names 

# id AIN5997.1 AIN5997.2 AIN7452.1 AIN7452.2 AIN8674.1 AIN8674.2 
# 1 1  01  02  02  02  02  02 
# 2 2  01  02  NA  NA  02  02 

私はまた、より良い解決策を追加しています。それは自動的にNAの値を扱い、列名とその順序について心配する必要はありません。

library(dplyr) 
library(tidyr) 
library(purrr) 

# example dataset 
dt = data.frame(id = 1:2, 
       AIN5997 = c("01/02", "01/02"), 
       AIN7452 = c("02/02", NA), 
       AIN8674 = c("02/02","02/02"), stringsAsFactors = F) 

# separate a given column of your initial dataset 
f = function(x) { dt %>% select_("id", x) %>% separate_(x, paste0(x, c(".1",".2"))) } 


names(dt)[2:4] %>%    # get names of columns you want to separate 
    map(f) %>%     # apply the function above to each name (will create a list of dataframes) 
    reduce(left_join, by="id") # join dataframes iteratively 

# id AIN5997.1 AIN5997.2 AIN7452.1 AIN7452.2 AIN8674.1 AIN8674.2 
# 1 1  01  02  02  02  02  02 
# 2 2  01  02  <NA>  <NA>  02  02 
+0

アントニオにお礼を言いますが、ちょっとした問題を除けば、完璧にうまくいきます。私の遺伝子型には値段がなく、時にはというコードがあります。前に言及した)、コマンドは2つの新しい値に分割できなかったようです。 また、私は不思議です:コマンドは、 "/"に従ってメイン値を分割する必要があることをどのように知っていますか?もう一度ありがとう! – Chrys

+0

コマンドは、英数字以外の値を使用して分割することがわかります。 https://rdrr.io/cran/tidyr/man/separate.htmlを確認するか、 '?separate'と入力してください。 – AntoniosK

+0

NA値を扱うようにコードを更新します。 – AntoniosK

0

tstrsplit()も使用できます。

# example dataset 
df <- data.frame(AIN5997 = c("01/02", "01/02"), 
       AIN7452 = c("02/02","01/01"), 
       AIN8674 = c("02/02","02/02"), stringsAsFactors = F) 
df 
df2 <- as.data.frame(unlist(lapply(df, data.table::tstrsplit, "/"), 
          recursive = FALSE)) 
df2 
colnames(df2) # change colnames 
colnames(df2) <- paste(substr(colnames(df2), 1, nchar(colnames(df2))-1), 
         substr(colnames(df2), nchar(colnames(df2)), nchar(colnames(df2))), 
         sep = ".") 
df2 
関連する問題