诀窍是以正确的顺序创建新名称,因此请确保提前对要分隔的列进行排序。
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