Как реплицировать имена столбцов, разделить их по разделителю «/» на несколько имен столбцов в R?

У меня эта матрица (она большая по размеру) "mymat". Мне нужно реплицировать столбцы, у которых есть «/» в имени столбца, совпадающем с «/», и сделать «resmatrix». Как я могу сделать это в R?

маймат

 a   b   IID:WE:G12D/V    GH:SQ:p.R172W/G   c
 1   3               4                  2   4
22   4               2                  2   4
 2   3               2                  2   4

рематрица

 a   b   IID:WE:G12D   IID:WE:G12V    GH:SQ:p.R172W    GH:SQ:p.R172G   c
 1   3             4             4                2                2   4
22   4             2             2                2                2   4
 2   3             2             2                2                2   4

person MAPK    schedule 22.07.2015    source источник


Ответы (2)


Узнайте, какие столбцы имеют «/», и скопируйте их, а затем переименуйте. Чтобы вычислить новые имена, просто разделите на / и замените последнюю букву на второе имя.

# which columns have '/' in them?
which.slash <- grep('/', names(mymat), value=T)
new.names <- unlist(lapply(strsplit(which.slash, '/'),
       function (bits) {
         # bits[1] is e.g. IID:WE:G12D and bits[2] is the V
         # take bits[1] and replace the last letter for the second colname
         c(bits[1], sub('.$', bits[2], bits[1]))
       }))

# make resmat by copying the appropriate columns
resmat <- cbind(mymat, mymat[, which.slash])
# order the columns to make sure the names replace properly
resmat <- resmat[, order(names(resmat))]
# put the new names in
names(resmat)[grep('/', names(resmat))] <- sort(new.names)

resmat выглядит так

#    a b c GH:SQ:p.R172G GH:SQ:p.R172W IID:WE:G12D IID:WE:G12V
# 1  1 3 4             2             2           4           4
# 2 22 4 4             2             2           2           2
# 3  2 3 4             2             2           2           2
person mathematical.coffee    schedule 22.07.2015

Вы можете использовать grep для получения индекса имен столбцов с помощью / («nm1»), реплицировать имена столбцов в «nm1», используя sub/scan для создания «nm2». Затем cbind столбцы, которые не являются "nm1", с реплицированными столбцами ("nm1"), измените имена столбцов на "nm2" и, при необходимости, order столбцы.

 #get the column index with grep
 nm1 <- grepl('/', names(df1))
 #used regex to rearrange the substrings in the nm1 column names
 #removed the `/` and use `scan` to split at the space delimiter
 nm2 <- scan(text=gsub('([^/]+)(.)/(.*)', '\\1\\2 \\1\\3', 
           names(df1)[nm1]), what='', quiet=TRUE)
 #cbind the columns that are not in nm1, with the replicate nm1 columns 
 df2 <- cbind(df1[!nm1], setNames(df1[rep(which(nm1), each= 2)], nm2))
 #create another index to find the starting position of nm1 columns
 nm3 <- names(df1)[1:(which(nm1)[1L]-1)] 
 #we concatenate the nm3, nm2, and the rest of the columns to match 
 #the expected output order
 df2N <- df2[c(nm3, nm2, setdiff(names(df1)[!nm1], nm3))]
 df2N 
 #   a b IID:WE:G12D IID:WE:G12V GH:SQ:p.R172W GH:SQ:p.R172G c
 #1  1 3           4           4             2             2 4
 #2 22 4           2           2             2             2 4
 #3  2 3           2           2             2             2 4

данные

df1 <-  structure(list(a = c(1L, 22L, 2L), b = c(3L, 4L, 3L),
`IID:WE:G12D/V` = c(4L, 
2L, 2L), `GH:SQ:p.R172W/G` = c(2L, 2L, 2L), c = c(4L, 4L, 4L)),
.Names = c("a", "b", "IID:WE:G12D/V", "GH:SQ:p.R172W/G", "c"),
class = "data.frame", row.names = c(NA, -3L))
person akrun    schedule 22.07.2015