отдельный столбец с неизвестным именем - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть такой фрейм данных:

structure(list(header = 1:10, ST.adk.fumC.gyrB.icd.mdh.purA.recA = c(" 10 10 11 4 8 8 8 2", 
" 48 6 11 4 8 8 8 2", " 58 6 4 4 16 24 8 14", " 88* 6* 4 12 1 20 12 7", 
" 117 20 45 41 43 5 32 2", " 7036 526 7 1 1 8 71 6", " 101 43 41 15 18 11 7 6", 
" 3595 112 11 5 12 8 88 86", " 117 20 45 41 43 5 32 2", " 744 10 11 135 8 8 8 2"
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))

Я хочу разделить второй столбец на отдельные столбцы, разделенные знаком "."в названии столбца.Однако не всегда известно, как называется имя столбца, поэтому я не могу использовать имя столбца в dplyr «отдельной» функции.

Я пробовал следующее:

library(dplyr)
library(stringr)
library(tidyr)

# get new column names
ids <- unlist(strsplit(names(df)[-1],
                              split = ".",
                              fixed = TRUE))

# get name of column to split
split_column <- names(df)[-1]

df %>%
separate(split_column, into = ids, extra = "merge")

Это работает в файле скрипта, который я использую, но когда я пишу скрипт, я получаю следующую ошибку:

Error: `var` must evaluate to a single number or a column name, not a character vector

Почему это работает, когда я запускаю его как обычно в RStudio, но когда яИсходный скрипт выдает эту ошибку?Кроме того, является ли это оптимальным способом фактического разбиения столбца с неизвестным именем на новые столбцы с неизвестными именами?

Я создаю сценарий со следующим кодом в другом файле сценария:

system(paste("Rscript script.R", opt$m, opt$o))

Где opt $ m и opt $ o являются путями к каталогам.Это прекрасно работает с аналогичным сценарием, который у меня есть, но с приведенным выше сценарием выдает ошибку.

Я надеялся на какую-то функцию, например Отдельный_кат, но пока еще не существует ..

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Вы можете использовать strsplit().

split <- do.call(rbind, strsplit(gsub("\\*", "", df[, -1]), " "))[, -1]
df1 <- data.frame(df[, 1], split)
df1[] <- lapply(df1, function(x) as.numeric(as.character(x)))
names(df1) <- unlist(strsplit(names(df), split = ".", fixed=TRUE))

> df1
   header   ST adk fumC gyrB icd mdh purA recA
1       1   10  10   11    4   8   8    8    2
2       2   48   6   11    4   8   8    8    2
3       3   58   6    4    4  16  24    8   14
4       4   88   6    4   12   1  20   12    7
5       5  117  20   45   41  43   5   32    2
6       6 7036 526    7    1   1   8   71    6
7       7  101  43   41   15  18  11    7    6
8       8 3595 112   11    5  12   8   88   86
9       9  117  20   45   41  43   5   32    2
10     10  744  10   11  135   8   8    8    2

Данные

df <-structure(list(header = 1:10, ST.adk.fumC.gyrB.icd.mdh.purA.recA = c(" 10 10 11 4 8 8 8 2", 
                                                                     " 48 6 11 4 8 8 8 2", " 58 6 4 4 16 24 8 14", " 88* 6* 4 12 1 20 12 7", 
                                                                     " 117 20 45 41 43 5 32 2", " 7036 526 7 1 1 8 71 6", " 101 43 41 15 18 11 7 6", 
                                                                     " 3595 112 11 5 12 8 88 86", " 117 20 45 41 43 5 32 2", " 744 10 11 135 8 8 8 2"
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))
0 голосов
/ 24 ноября 2018

Практически то же решение, что и в вашем примере, с несколькими настройками.Вот как я бы это сделал, предполагая, что вы хотите удалить '*' в столбцах:

library(tidyverse)
library(hablar)

# Vector of new column names
ids <- simplify(strsplit(names(df)[-1], 
                         split = ".", 
                         fixed = T))

# Seperate second column
df %>%
  mutate_at(2, funs(trimws(gsub("\\*", "", .)))) %>%
  separate(2, into = ids, extra = "merge", sep = " ") %>% 
  retype()

дает вам:

# A tibble: 10 x 9
   header    ST   adk  fumC  gyrB   icd   mdh  purA  recA
    <int> <int> <int> <int> <int> <int> <int> <int> <int>
 1      1    10    10    11     4     8     8     8     2
 2      2    48     6    11     4     8     8     8     2
 3      3    58     6     4     4    16    24     8    14
 4      4    88     6     4    12     1    20    12     7
 5      5   117    20    45    41    43     5    32     2
 6      6  7036   526     7     1     1     8    71     6
 7      7   101    43    41    15    18    11     7     6
 8      8  3595   112    11     5    12     8    88    86
 9      9   117    20    45    41    43     5    32     2
10     10   744    10    11   135     8     8     8     2
...