使用dplyr递归遍历列名和单独的字段

使用dplyr递归遍历列名和单独的字段,r,dplyr,R,Dplyr,我想迭代数据帧的列名,然后使用dplyr,使用行字段中的分隔符(->)分隔字段。以下是数据集的外观: dput(df) structure(list(v1 = c("Silva->Mark", "Brandon->Livo", "Mango->Apple"), v2 = c("Austin", "NA ", "Orange"), v3 = c("James -> Jacy","NA->Jane", "ap

我想迭代数据帧的列名,然后使用dplyr,使用行字段中的分隔符(->)分隔字段。以下是数据集的外观:

dput(df)
structure(list(v1 = c("Silva->Mark", "Brandon->Livo", "Mango->Apple"),
               v2 = c("Austin",  "NA ", "Orange"),
               v3 = c("James -> Jacy","NA->Jane", "apple -> Orange")),
          class = "data.frame", row.names = c(NA,  -3L))
现在,我编写了一段代码,在第v1列和第v3列的行上过滤掉带有分隔符(->)的列名。代码如下:

rows_true <- apply(df,2,function(x) any(sapply(x,function(y)grepl("->",y))))
ss<-df[,rows_true]


一种涉及
dplyr
tidyr
的可能性是:

df %>%
 select(v1, v3) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid) %>%
 separate_rows(val, sep = "->", convert = TRUE) %>%
 group_by(rowid) %>%
 mutate(val = trimws(val),
        var = make.unique(var)) %>%
 ungroup() %>%
 spread(var, val) %>%
 select(-rowid)

  v1      v1.1  v3    v3.1  
  <chr>   <chr> <chr> <chr> 
1 Silva   Mark  James Jacy  
2 Brandon Livo  <NA>  Jane  
3 Mango   Apple apple Orange
df%>%
选择(v1,v3)%>%
rowid_到_列()%>%
聚集(var,val,-rowid)%>%
单独的_行(val,sep=“->”,convert=TRUE)%>%
分组依据(rowid)%>%
突变(val=trimws(val),
var=make.unique(var))%>%
解组()%>%
价差(var,val)%>%
选择(-rowid)
v1.1 v3.1
1西尔瓦·马克·詹姆斯·杰西
2布兰登·利沃·简
3芒果苹果橙
或进一步匹配预期输出:

df %>%
 select(v1, v3) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid) %>%
 separate_rows(val, sep = "->", convert = TRUE) %>%
 group_by(rowid, var) %>%
 mutate(val = trimws(val),
        var2 = if_else(row_number() == 2, paste0(var, "_old"), paste0(var, "_new"))) %>%
 ungroup() %>%
 select(-var) %>%
 spread(var2, val) %>%
 select(-rowid)

  v1_new  v1_old v3_new v3_old
  <chr>   <chr>  <chr>  <chr> 
1 Silva   Mark   James  Jacy  
2 Brandon Livo   <NA>   Jane  
3 Mango   Apple  apple  Orange
df%>%
选择(v1,v3)%>%
rowid_到_列()%>%
聚集(var,val,-rowid)%>%
单独的_行(val,sep=“->”,convert=TRUE)%>%
分组依据(rowid,var)%>%
突变(val=trimws(val),
var2=if_-else(行号()==2,粘贴0(var,“_-old”)、粘贴0(var,“_-new”))%>%
解组()%>%
选择(-var)%>%
价差(var2,val)%>%
选择(-rowid)
v1_新v1_旧v3_新v3_旧
1西尔瓦·马克·詹姆斯·杰西
2布兰登·利沃·简
3芒果苹果橙

一种可能涉及到
dplyr
tidyr

df %>%
 select(v1, v3) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid) %>%
 separate_rows(val, sep = "->", convert = TRUE) %>%
 group_by(rowid) %>%
 mutate(val = trimws(val),
        var = make.unique(var)) %>%
 ungroup() %>%
 spread(var, val) %>%
 select(-rowid)

  v1      v1.1  v3    v3.1  
  <chr>   <chr> <chr> <chr> 
1 Silva   Mark  James Jacy  
2 Brandon Livo  <NA>  Jane  
3 Mango   Apple apple Orange
df%>%
选择(v1,v3)%>%
rowid_到_列()%>%
聚集(var,val,-rowid)%>%
单独的_行(val,sep=“->”,convert=TRUE)%>%
分组依据(rowid)%>%
突变(val=trimws(val),
var=make.unique(var))%>%
解组()%>%
价差(var,val)%>%
选择(-rowid)
v1.1 v3.1
1西尔瓦·马克·詹姆斯·杰西
2布兰登·利沃·简
3芒果苹果橙
或进一步匹配预期输出:

df %>%
 select(v1, v3) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid) %>%
 separate_rows(val, sep = "->", convert = TRUE) %>%
 group_by(rowid, var) %>%
 mutate(val = trimws(val),
        var2 = if_else(row_number() == 2, paste0(var, "_old"), paste0(var, "_new"))) %>%
 ungroup() %>%
 select(-var) %>%
 spread(var2, val) %>%
 select(-rowid)

  v1_new  v1_old v3_new v3_old
  <chr>   <chr>  <chr>  <chr> 
1 Silva   Mark   James  Jacy  
2 Brandon Livo   <NA>   Jane  
3 Mango   Apple  apple  Orange
df%>%
选择(v1,v3)%>%
rowid_到_列()%>%
聚集(var,val,-rowid)%>%
单独的_行(val,sep=“->”,convert=TRUE)%>%
分组依据(rowid,var)%>%
突变(val=trimws(val),
var2=if_-else(行号()==2,粘贴0(var,“_-old”)、粘贴0(var,“_-new”))%>%
解组()%>%
选择(-var)%>%
价差(var2,val)%>%
选择(-rowid)
v1_新v1_旧v3_新v3_旧
1西尔瓦·马克·詹姆斯·杰西
2布兰登·利沃·简
3芒果苹果橙

下面是使用
dplyr
purr
stringr
的不同方法

library(dplyr)
library(purrr)
library(stringr)

# Detect the columns with at least on "->"
my_df_cols <- map_lgl(my_df, ~ any(str_detect(., "->")))

my_df %>% 
  # Select only the columns with at least "->"
  select(which(my_df_cols)) %>% 
  # Mutate these columns and only keep the mutated columns with new names
  transmute_all(list(old = ~ str_split(., "->", simplify = TRUE)[, 1], 
                     new = ~ str_split(., "->", simplify = TRUE)[, 2]))

#    v1_old v3_old v1_new  v3_new
# 1   Silva James    Mark    Jacy
# 2 Brandon     NA   Livo    Jane
# 3   Mango apple   Apple  Orange
库(dplyr)
图书馆(purrr)
图书馆(stringr)
#检测至少为“->”的列
我的_df_cols%
#仅选择至少带“->”的列
选择(哪一个(my_df_cols))%>%
#对这些列进行变异,并仅保留具有新名称的变异列
transmute_all(list(old=~str_split(,“->”,simplify=TRUE)[,1],
new=~str_split(,“->”,simplify=TRUE)[,2]))
#v1_旧v3_旧v1_新v3_新
#1席尔瓦·詹姆斯·马克·杰西
#2布兰登·纳利沃·简
#3芒果苹果橙

下面是使用
dplyr
purr
stringr
的不同方法

library(dplyr)
library(purrr)
library(stringr)

# Detect the columns with at least on "->"
my_df_cols <- map_lgl(my_df, ~ any(str_detect(., "->")))

my_df %>% 
  # Select only the columns with at least "->"
  select(which(my_df_cols)) %>% 
  # Mutate these columns and only keep the mutated columns with new names
  transmute_all(list(old = ~ str_split(., "->", simplify = TRUE)[, 1], 
                     new = ~ str_split(., "->", simplify = TRUE)[, 2]))

#    v1_old v3_old v1_new  v3_new
# 1   Silva James    Mark    Jacy
# 2 Brandon     NA   Livo    Jane
# 3   Mango apple   Apple  Orange
库(dplyr)
图书馆(purrr)
图书馆(stringr)
#检测至少为“->”的列
我的_df_cols%
#仅选择至少带“->”的列
选择(哪一个(my_df_cols))%>%
#对这些列进行变异,并仅保留具有新名称的变异列
transmute_all(list(old=~str_split(,“->”,simplify=TRUE)[,1],
new=~str_split(,“->”,simplify=TRUE)[,2]))
#v1_旧v3_旧v1_新v3_新
#1席尔瓦·詹姆斯·马克·杰西
#2布兰登·纳利沃·简
#3芒果苹果橙

我们也可以从
splitstackshape

#Detect columns with "->"
cols <- names(df)[colSums(sapply(df, grepl,  pattern = "->")) > 1]
#Remove unwanted whitespaces before and after "->"
df[cols] <- lapply(df[cols],  function(x) gsub("\\s+", "", x))

#Split into new columns specifying sep as "->"
splitstackshape::cSplit(df[cols], cols, sep = "->")

#      v1_1  v1_2  v3_1   v3_2
#1:   Silva  Mark James   Jacy
#2: Brandon  Livo  <NA>   Jane
#3:   Mango Apple apple Orange
#检测带“->”的列
cols 1]
#删除“->”前后不需要的空格

df[cols]我们也可以从
splitstackshape

#Detect columns with "->"
cols <- names(df)[colSums(sapply(df, grepl,  pattern = "->")) > 1]
#Remove unwanted whitespaces before and after "->"
df[cols] <- lapply(df[cols],  function(x) gsub("\\s+", "", x))

#Split into new columns specifying sep as "->"
splitstackshape::cSplit(df[cols], cols, sep = "->")

#      v1_1  v1_2  v3_1   v3_2
#1:   Silva  Mark James   Jacy
#2: Brandon  Livo  <NA>   Jane
#3:   Mango Apple apple Orange
#检测带“->”的列
cols 1]
#删除“->”前后不需要的空格

df[cols]为了完整起见,这里还有一个使用
data.table()
的解决方案

与目前发布的其他答案存在一些差异:

  • 无需事先确定要拆分的列。相反,不带
    “->”
    的列将从结果中动态删除
  • 用于拆分的正则表达式包括周围的空白(如果有)
    “*->*”
    。这样可以避免在生成的片段上调用
    trimws()
    ,或者事先删除空白


为了完整起见,这里还有一个使用
data.table()
的解决方案

与目前发布的其他答案存在一些差异:

  • 无需事先确定要拆分的列。相反,不带
    “->”
    的列将从结果中动态删除
  • 用于拆分的正则表达式包括周围的空白(如果有)
    “*->*”
    。这样可以避免在生成的片段上调用
    trimws()
    ,或者事先删除空白


你能编辑它使我只拆分列吗,就像我不想在结果中有V2一样,因为我有多个列,很难分析上一个结果中没有拆分的列。你能编辑它使我只拆分列吗,就像我不想在结果中包含V2一样,因为我有多个列,并且很难在最后一个结果中分析没有拆分的列