拆分字符串并将其添加为新行

MFR*_*MFR 11 r

我有以下数据集:

df<-data.frame (fact= c("a,b,c,d","f,g,h,v"), value = c("0,1,0,1" , "0,0,1,0"))
Run Code Online (Sandbox Code Playgroud)

这是数据:

   fact   value
1 a,b,c,d 0,1,0,1
2 f,g,h,v 0,0,1,0
Run Code Online (Sandbox Code Playgroud)

我希望在值为1时拆分它.所以,我的理想输出是:

 fact     value

1:  a,b     0,1
2:  c,d     0,1
3: f,g,h    0,0,1
4:  v       0
Run Code Online (Sandbox Code Playgroud)

首先,我想我可能会找到一种使用方式cut:

cut(as.numeric(strsplit(as.character(df$value), split = ",")), breaks =1)
Run Code Online (Sandbox Code Playgroud)

但我的尝试都没有结束.

eip*_*i10 6

首先,我们在分割字符串factvalue成单独的值和将它们堆叠,使得在数据帧中的每个变值的列中.现在,使用value,我们希望每次运行零后跟1成为一个组.这些是我们想要在最后粘贴在一起的值组.我们将使用dplyr在每个组上单独操作以返回最终数据帧.

library(dplyr) 
library(purrr)  # For map function
library(tidyr)  # For separate_rows function

df %>% 
  separate_rows(fact, value, sep=",") %>%
  mutate(group = lag(cumsum(value == 1), default=0)) %>%
  group_by(group) %>%
  summarise(fact = paste(fact, collapse=","),
            value = paste(value, collapse=",")) %>%
  select(-group)     

   fact value 
1   a,b   0,1
2   c,d   0,1
3 f,g,h 0,0,1
4     v     0
Run Code Online (Sandbox Code Playgroud)


aic*_*hao 5

一种方式是分割为特征向量factvalue由原始数据帧","使用strsplit,然后确定第一的位置"1"在分割value秒.然后使用这个位置来确定两方分factvalue:

sv <- strsplit(df$value,",")
sf <- strsplit(df$fact,",")
pos <- sapply(sv, function(sv) {j <- which(sv=="1"); if (length(j)==0) NA else j[1]})
out <- do.call(rbind,lapply(1:length(pos),function(i,sv,sf,pos) {
  if (is.na(pos[i]) || pos[i] == length(sf[[i]])) 
    data.frame(fact=toString(sf[[i]]),value=toString(sv[[i]])) 
  else 
    data.frame(fact=c(toString(sf[[i]][1:pos[i]]),
                      toString(sf[[i]][(pos[i]+1):length(sf[[i]])])),
               value=c(toString(sv[[i]][1:pos[i]]),
                       toString(sv[[i]][(pos[i]+1):length(sv[[i]])])))
  },sv,sf,pos))
##     fact   value
##1    a, b    0, 1
##2    c, d    0, 1
##3 f, g, h 0, 0, 1
##4       v       0
Run Code Online (Sandbox Code Playgroud)

这个回答假设有一个"1"value分裂.如果没有或者是否"1"在结尾处value,则该行df不会在输出中分割.


the*_*ail 5

另一个基础R尝试:

sf <- strsplit(as.character(df$fact), ",")
sv <- strsplit(as.character(df$value), ",")
spl <- lapply(sv, function(x) -rev(cumsum(as.numeric(rev(x)))) )
#[[1]]
#[1] -2 -2 -1 -1
#
#[[2]]
#[1] -1 -1 -1  0

joinfun <- function(x) sapply(unlist(Map(split, x, spl), rec=FALSE), paste, collapse=",")

# to show you what is happening:
#> Map(split, sf, spl)
#[[1]]
#[[1]]$`-2`
#[1] "a" "b"
#
#[[1]]$`-1`
#[1] "c" "d"
# 
#
#[[2]]
#[[2]]$`-1`
#[1] "f" "g" "h"
#
#[[2]]$`0`
#[1] "v"

data.frame(fact  = joinfun(sf), value = joinfun(sv) )
#   fact value
#1   a,b   0,1
#2   c,d   0,1
#3 f,g,h 0,0,1
#4     v     0
Run Code Online (Sandbox Code Playgroud)


jaz*_*rro 5

一种data.table方法如下.您在分割的每个元素factvalue使用cSplit()splitstackshape包.这将以长格式创建data.table.获得结果后,使用diff()和创建一个小于0的cumsum()任何地方创建一个组变量value,R创建一个新组.然后,你想要同时适用paste()factvalue.你可以使用这个来实现lapply(.SD ...).这是等价summarise_at()dplyr包.最后,删除组变量.

library(splitstackshape)
library(data.table)

cSplit(df, splitCols = c("fact", "value"),
       direction = "long", sep = ",") -> temp

temp[, group := cumsum(c(FALSE, diff(value) < 0))][,
       lapply(.SD, function(x){paste(x, collapse = ",")}),
       .SDcols = fact:value,
       by = group][, group :=NULL] -> out

#    fact value
#1:   a,b   0,1
#2:   c,d   0,1
#3: f,g,h 0,0,1
#4:     v     0
Run Code Online (Sandbox Code Playgroud)