使用dplyr创建字符串列表

使用dplyr创建字符串列表,r,dataframe,dplyr,R,Dataframe,Dplyr,我想在R中创建一个新列,该列根据是否有多个列标记为“X”来连接多个字符串 以下是我掌握的数据: Column1 Column2 Column3 Column4 X X X X X X X X 我想创建一个新的Column5,如果输入了“X”,它将包括以下每一项: Column1: 'Texa

我想在R中创建一个新列,该列根据是否有多个列标记为“X”来连接多个字符串

以下是我掌握的数据:

Column1   Column2   Column3   Column4
      X         X         X         
      X                   X         X
      X                             X
我想创建一个新的Column5,如果输入了“X”,它将包括以下每一项:

Column1: 'Texas'
Column2: 'California'
Column3: 'New Jersey'
Column4: 'Oklahoma'

我可以用R中相当多的代码来实现这一点,但我认为使用dplyr有一种更简洁的方式

以下是一种可行的方法:

df = data_frame(c1='x', c2=c('x', NA, NA), c3=c('x', 'x', NA), c4=c(NA, 'x', 'x'))
values = c('TX', 'CA', 'NJ', 'OK')
df$c5 = sapply(df, function(x) !is.na(x)) %>% 
    apply(MARGIN=1, FUN=function(x) paste(values[x], collapse=', '))
df

# A tibble: 3 x 5
  c1    c2    c3    c4    c5                           
  <chr> <chr> <chr> <chr> <chr>                        
1 x     x     x     NA    Texas, California, New Jersey
2 x     NA    x     x     Texas, New Jersey, Oklahoma  
3 x     NA    NA    x     Texas, Oklahoma 
sapply通过数据帧循环检查值是否丢失,以获得真/假值矩阵。然后循环该矩阵,将T/F值行传递给一个匿名函数,该函数对值进行索引并粘贴结果。链式sapply和apply函数的输出是您要查找的字符串的向量,其长度等于df中的行数。因此,您可以将其设置为新列。希望这是有道理的

df <- data.frame(c1 = c(T,T,T),
                 c2 = c(T,F,F),
                 c3 = c(T,T,F),
                 c4 = c(F,T,T))
现在您可以测试每一列以获得真正列的索引,然后从sts向量中获取相应的状态并将它们粘贴在一起

在上面的示例中,数据帧包含TRUE和FALSE,但是如果您想使用字符值(例如“X”)来选择单元格,只需将which语句中的测试从==TRUE更改为=='X',例如

请注意,这当前要求您指定列名。这样做的好处是,如果您有其他不想考虑的列,那么它不会有任何问题

df %>%
    rowwise() %>%
    mutate(c5 = paste0(sts[which(c(c1,c2,c3,c4) == TRUE)], collapse = ', '))

Source: local data frame [3 x 5]
Groups: <by row>

# A tibble: 3 x 5
  c1    c2    c3    c4    c5                           
  <lgl> <lgl> <lgl> <lgl> <chr>                        
1 TRUE  TRUE  TRUE  FALSE Texas, California, New Jersey
2 TRUE  FALSE TRUE  TRUE  Texas, New Jersey, Oklahoma  
3 TRUE  FALSE FALSE TRUE  Texas, Oklahoma      

可能需要根据数据类型进行一些调整——我在这里粘贴了一些内容,没有复选标记的列就是空白的

我使用的方法是创建行号来标识开始时使用的观察值,转换为长形数据,按行号分组,查找被选中的状态,将它们折叠为一个字符串,然后重新调整为宽格式。这样做的原因是它可以很好地扩展,不管有多少个州,因为我没有做像德克萨斯州==X&加利福尼亚州==X&。。。这需要硬编码

第一个主要步骤是使用tidyr::gather,这样就有了行、所有可能的状态值以及复选标记或空格

图书馆管理员 df%读表 df%>% setNamescTexas,加利福尼亚州,新泽西州,俄克拉何马州%>% mutaterow=行数%>% gatherkey=state,value=value,-行 >一个tibble:12x3 >行状态值 > >德克萨斯州X >德克萨斯州X >德克萨斯州X >4 1加利福尼亚X >5.2加利福尼亚州 >加利福尼亚州 >7 1新泽西X >8 2新泽西X >9.3新泽西州 >10 1俄克拉荷马州 >11.2俄克拉荷马X >12 3俄克拉荷马X 然后我按行号分组,并使用stringr便利函数。str_whichvalue,^X$查找值包含正则表达式^X$的位置。使用它作为状态的索引可以获取状态中对应于X值的条目。然后我将这些字符串折叠成一个字符串列,并使用tidyr::spread将其重新转换为宽格式

df%>% setNamescTexas,加利福尼亚州,新泽西州,俄克拉何马州%>% mutaterow=行数%>% gatherkey=state,value=value,-row%>% 组\u byrow%>% mutatestates=state[str_whichvalue,^X$]%%>%pastecollapse=,%%>% spreadkey=状态,value=值 >一个tibble:3x6 >分组:第[3]行 >世界其他地区加利福尼亚州、新泽西州、俄克拉何马州、德克萨斯州 > >德克萨斯州,加利福尼亚州,新泽西州 >德克萨斯州、新泽西州、俄克拉荷马州X >德克萨斯州,俄克拉荷马州
由v0.2.1于2018年10月11日创建

如果选中多个列,是否要同时通过多个状态?第2排:德克萨斯州,纽约州Jersey@divibisan是的,就是这个意思,每个条目之间只有一个逗号和空格。示例:德克萨斯州,新泽西州您应该包含一段代码,以演示如何将“x”数据帧转换为具有T/F值的数据帧。像df%>%这样的变异!是的。
df %>%
    rowwise() %>%
    mutate(c5 = paste0(sts[which(c(c1,c2,c3,c4) == TRUE)], collapse = ', '))

Source: local data frame [3 x 5]
Groups: <by row>

# A tibble: 3 x 5
  c1    c2    c3    c4    c5                           
  <lgl> <lgl> <lgl> <lgl> <chr>                        
1 TRUE  TRUE  TRUE  FALSE Texas, California, New Jersey
2 TRUE  FALSE TRUE  TRUE  Texas, New Jersey, Oklahoma  
3 TRUE  FALSE FALSE TRUE  Texas, Oklahoma