名称未知的单独列

时间:2018-11-23 12:43:53

标签: r dplyr tidyr

我有一个像这样的数据框:

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是目录路径。可以与我拥有的类似脚本一起使用,但上面的脚本会引发错误。

我希望有某种功能,例如Separate_at,但目前还不存在。

2 个答案:

答案 0 :(得分:1)

您可以使用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"
))

答案 1 :(得分:0)

与您的示例几乎相同的解决方案,但有一些调整。假设您要删除以下各列中的print(np.arange((len(df) // N + 1) * N).reshape(-1, N)) [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] print (np.arange((len(df) // N + 1) * N).reshape(-1, N)[:, -M:]) [[ 2 3 4] [ 7 8 9] [12 13 14] [17 18 19]] print (np.arange((len(df) // N + 1) * N).reshape(-1, N)[:, -M:].ravel()) [ 2 3 4 7 8 9 12 13 14 17 18 19] print(np.intersect1d(df.index, pos)) [ 2 3 4 7 8 9 12 13 14] ,这就是我要这样做的方式:

'*'

给您

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()