将列变量拆分为新列并结合原始列名称

时间:2018-05-29 08:29:38

标签: r tidyverse

我有一个数据框,在多个单元格中有多个条目。有三种列:仅包含1/0的列,包含1/0和其他条目的列,以及不包含1/0的列。

我想要做的是将包含一些其他值(通常是两个或更多条目)的所有列拆分为x个新列,列名为+列中每个唯一值的单元格值,和1/0是否存在。只有1/0的所有列都将保留原样。

注意:我的原始数据框架较大且列数较多。此外,单元格中的内容可能会根据数据框架而有所不同,无论单元格中的条目数是多少,我都希望它能够正常工作。另请注意,我有不希望被拆分的列,因为它们只包含1/0(例如ex.emrY),或者因为它们包含其他数据(例如,例如T_CIP)。

数据框:

main()

它看起来像什么:

structure(list(id = 1:10, emrA = c("I219V, T286A", "I219V", "I219V", 
"I219V", "I219V", "R164H, I219V", "R164H, I219V", "R164H, I219V", 
"R164H, I219V", "R164H, I219V"), gyrA_8 = c("S83L,678E", "D87N", 
"S83L,252G", "S83L,678E", "S83L,678E", "S83L,828T", "S83L,828T", 
"S83L,828T", "S83L,828T", "S83L,828T"), emrY = c("0", "1", "1", 
"1", "1", "1", "1", "1", "1", "1"), T_CIP = c(0.25, 0.12, 0.12, 
0.25, 0.25, 0.5, 2, 1, 1, 2)), .Names = c("id", "emrA", "gyrA_8", 
"emrY", "T_CIP"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-10L))

我最终希望得到什么:

     id emrA         gyrA_8    emrY  T_CIP
      1 I219V, T286A S83L,678E 0     0.25
      2 I219V        D87N      1     0.12
      3 I219V        S83L,252G 1     0.12
      4 I219V        S83L,678E 1     0.25
      5 I219V        S83L,678E 1     0.25
      6 R164H, I219V S83L,828T 1     0.5
      7 R164H, I219V S83L,828T 1     2
      8 R164H, I219V S83L,828T 1     1
      9 R164H, I219V S83L,828T 1     1
     10 R164H, I219V S83L,828T 1     2

emrY列未被拆分,因为它只包含1/0。 T_CIP(和它的其他类似列)没有拆分,因为它包含其他数据。

有没有办法用tidyverse-packages做到这一点?

修改

我不认为标记为重复的问题会回答我的问题 - 他们没有多个内容不同的列,问题本身就是关于虚拟变量的问题,并不能解释我在尝试什么在这里做。

1 个答案:

答案 0 :(得分:1)

我首先要设置要处理的列名:

names_to_proc <- c("emrA", "gyrA_8")

让我们构造一个函数,为每列产生一组新的1/0列:

# @ col_name is one of the names_to_proc
AddCol <- function(df, col_name) {
    # split rows by delimeters
    string_to_proc <- df %>% select(!!col_name) %>%
       unlist() %>% str_split(regex("\\, |\\,")) 
    # find unique entries
    unique_strings <- string_to_proc %>%
       unlist() %>% unique()
    # construct names of the new columns
    cols_names <- paste(col_name, unique_strings, sep = "_")
    # construct 0/1-content columns for each unique entry
    cols_content <- sapply(function(i) {
            as.integer(unlist(lapply(function(Z) any(Z %in% unique_strings[i]), 
            X = string_to_proc)))
        }, X = seq_along(unique_strings))
    res <- data.frame(cols_content)
    names(res) <- cols_names
    return(res)
}

最后,应用该函数来获取应替换已处理列的列集。为names_to_proc的每个值计算的1/0数据帧与bind_cols()绑定在一起:

# @ df_test is the initial data frame
cols_to_add <- sapply(function(i) {AddCol(df = df_test, col_name = names_to_proc[i])}, 
    X = seq_along(names_to_proc)) %>% 
    bind_cols()

将结果块添加到初始数据框中,并进行一些额外的转换,以获得所需格式的数据:

df_test %>% bind_cols(cols_to_add) %>% 
    select(-(2:3)) %>%
    select(-(emrY:T_CIP), everything())

希望,这有帮助。