使用NA在数据框中拆分列

时间:2018-08-16 07:58:51

标签: r dataframe split

我有这样的df

df <- data.frame(FOO = c('A|B|C', 'A|B', 'B|C', 'A', 'C'))

> df
    FOO
1 A|B|C
2   A|B
3   B|C
4     A
5     C

我想要一个这样的输出:

> df
  X1 X2 X3
1 A  B  C
2 A  B
3    B  C
4 A
5       C

到目前为止,我尝试使用以下示例:Split column at delimiter in data frame,但它不会在不重复值的情况下拆分列,我得到的是:

df <- data.frame(do.call('rbind', strsplit(as.character(df$FOO),'|',fixed=TRUE)))

> df
  X1 X2 X3
1  A  B  C
2  A  B  A
3  B  C  B
4  A  A  A
5  C  C  C

我也收到此警告:

  

警告消息:在rbind(c(“ A”,“ B”,“ C”),c(“ A”,“ B”),c(“ B”,“ C”)中,   “ A”,“ C”):结果的列数不是向量的倍数   长度(arg 2)

在这些情况下我该怎么办?最好使用baseR

5 个答案:

答案 0 :(得分:9)

只需:

splt <- strsplit(as.character(df$FOO),"\\|")
all_val <- sort(unique(unlist(splt)))
t(sapply(splt,function(x){all_val[!(all_val %in% x)]<-NA;all_val}))


#     [,1] [,2] [,3]
#[1,] "A"  "B"  "C" 
#[2,] "A"  "B"  NA  
#[3,] NA   "B"  "C" 
#[4,] "A"  NA   NA  
#[5,] NA   NA   "C" 

数据:

df <- data.frame(FOO = c('A|B|C', 'A|B', 'B|C', 'A', 'C'))

请注意:

我的版本是base::(不需要库)且一般:

它还可以与:

一起使用
df <- data.frame(FOO = c('A|B|C', 'A|B', 'B|C', 'A', 'C', 'B|D|F'))

答案 1 :(得分:6)

忽略了OP要求的base R解决方案。请尝试@ AndreElrico,@ r.user.05apr或@milan的解决方案。


这可以通过cSplit_e软件包中的splitstackshape完成:

library(splitstackshape)
cSplit_e(
  data = df,
  split.col = "FOO",
  sep = "|",
  mode = "value",
  type = "character",
  fill = " ",
  drop = TRUE
)
#  FOO_A FOO_B FOO_C
#1     A     B     C
#2     A     B      
#3           B     C
#4     A            
#5                 C

在以下df的情况下也可以使用(请参见上文OP的注释)。

(df1 <- data.frame(FOO = c('A|B|C', 'A|B', 'B|C', 'A', 'C', 'B|D|F')))
#    FOO
#1 A|B|C
#2   A|B
#3   B|C
#4     A
#5     C
#6 B|D|F

cSplit_e(df1, "FOO", "|", "value",  "character", TRUE, fill = " ")
#  FOO_A FOO_B FOO_C FOO_D FOO_F
#1     A     B     C            
#2     A     B                  
#3           B     C            
#4     A                        
#5                 C            
#6           B           D     F

答案 2 :(得分:4)

在基数R中:

%macro Create_subset(Row);
    data _NULL_;
        set T1(firstobs=&row obs=&row.);
            CALL SYMPUT("Condition", Cond);
    run;

    data Subset_&row.; 
        set T1; 
     %qsysfunc(dequote(&Condition.)); 
     applied_cond = &Condition.;
    run;
%mend Create_subset;
data _NULL_;
    set T1; 
    call execute('%nrstr(%Create_subset('||strip(_N_)|| '))');
run;

答案 3 :(得分:2)

使用uniquestrsplit查找所有唯一值(在这种情况下为ABC)。使用grep搜索唯一值,并在匹配时返回值,否则返回character(0)cbind得到的字符。使用applyifelsecharacter(0)替换为NA

vals <- unique(unlist(sapply(a1, function(x) strsplit(x, '|', fixed = T))))

out <- NULL
for(i in vals){
  out <- cbind(out, as.character((lapply(df$FOO, function(x) grep(x, i, value=T)))))
}

apply(out, 2, function(x) ifelse(x=="character(0)", NA, x))

     [,1] [,2] [,3]
[1,] "A"  "B"  "C" 
[2,] "A"  "B"  NA  
[3,] NA   "B"  "C" 
[4,] "A"  NA   NA  
[5,] NA   NA   "C" 

答案 4 :(得分:0)

您也可以尝试使用tidyverse

library(tidyverse)
df %>%
  rownames_to_column() %>% 
  separate_rows(FOO, sep="[|]") %>% 
  mutate(L=factor(FOO, labels = paste0("X",1:length(unique(FOO))))) %>% 
  spread(L, FOO) %>% 
  select(-1)
    X1   X2   X3
1    A    B    C
2    A    B <NA>
3 <NA>    B    C
4    A <NA> <NA>
5 <NA> <NA>    C

它通常也可以正常工作df <- data.frame(FOO = c('A|B|C', 'A|B', 'B|C', 'A', 'C', 'B|D|F'))。此外,您可以设置级别,例如B> C> A自己使用mutate步骤中的factor函数中的levels = c("B", "C", "A")