仅将 tidyr separate 应用于特定行
Applying tidyr separate only to specific rows
我正在尝试使用 tidyr 分隔数据框中的一列,同时仅将其应用于特定行。虽然 dplyr::filter 完成了这项工作,但它忽略了我的其余数据。有没有一种干净的方法可以将 tidyr 应用于特定行,同时保持其余数据不变?
这是我的问题的一个例子:
#creating DF for the example
df<-data.frame(var_a=letters[1:5],
var_b=c(sample(1:100,5)),
text=c("foo_bla","here_do","oh_yes","baa","land"))
给我这个:
var_a var_b text
1 a 10 foo_bla
2 b 58 here_do
3 c 34 oh_yes
4 d 1 baa
5 e 47 land
#separating one col:
clean_df<-df %>% separate(text,into=c("first","sec"),sep="_",remove=F)
clean_df
var_a var_b text first sec
1 a 10 foo_bla foo bla
2 b 58 here_do here do
3 c 34 oh_yes oh yes
4 d 1 baa baa <NA>
5 e 47 land land <NA>
I want to split only the "here_do" row.
Thanks in advance for any kind of help!
我们可以在 base R
中通过替换 'text' 列中 'here_do' 的分隔符来做到这一点,即使用 sub
将其更改为 'here,do',使用 read.csv
和 cbind
读取原始数据集
cbind(df, read.csv(text=sub("(?<=here)_(?=do)", ",", df$text,
perl = TRUE), header=FALSE, col.names = c("first", "sec")))
# var_a var_b text first sec
#1 a 93 foo_bla foo_bla
#2 b 51 here_do here do
#3 c 65 oh_yes oh_yes
#4 d 70 baa baa
#5 e 32 land land
或者如果我们需要 tidyr
解决方案,请使用 extract
library(tidyr)
extract(df, text, into = c("first", "sec"), "(here)_(do)", remove = FALSE)
# var_a var_b text first sec
#1 a 93 foo_bla <NA> <NA>
#2 b 51 here_do here do
#3 c 65 oh_yes <NA> <NA>
#4 d 70 baa <NA> <NA>
#5 e 32 land <NA> <NA>
另一种方法:
cols_to_split = c('here_do')
clean_df <-df %>%
filter(text %in% cols_to_split) %>%
tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>%
bind_rows(filter(df, !text %in% cols_to_split))
# var_a var_b text first sec
#1 b 7 here_do here do
#2 a 26 foo_bla <NA> <NA>
#3 c 23 oh_yes <NA> <NA>
#4 d 2 baa <NA> <NA>
#5 e 67 land <NA> <NA>
如果您需要保留第 'first' 列中的其余行,您可以使用:
clean_df <-df %>%
filter(text %in% cols_to_split) %>%
tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>%
bind_rows(filter(df, !text %in% cols_to_split)) %>%
mutate(first = ifelse(is.na(first), as.character(text), first))
# var_a var_b text first sec
#1 b 7 here_do here do
#2 a 26 foo_bla foo_bla <NA>
#3 c 23 oh_yes oh_yes <NA>
#4 d 2 baa baa <NA>
#5 e 67 land land <NA>
我正在尝试使用 tidyr 分隔数据框中的一列,同时仅将其应用于特定行。虽然 dplyr::filter 完成了这项工作,但它忽略了我的其余数据。有没有一种干净的方法可以将 tidyr 应用于特定行,同时保持其余数据不变?
这是我的问题的一个例子:
#creating DF for the example
df<-data.frame(var_a=letters[1:5],
var_b=c(sample(1:100,5)),
text=c("foo_bla","here_do","oh_yes","baa","land"))
给我这个:
var_a var_b text 1 a 10 foo_bla 2 b 58 here_do 3 c 34 oh_yes 4 d 1 baa 5 e 47 land
#separating one col:
clean_df<-df %>% separate(text,into=c("first","sec"),sep="_",remove=F)
clean_df
var_a var_b text first sec 1 a 10 foo_bla foo bla 2 b 58 here_do here do 3 c 34 oh_yes oh yes 4 d 1 baa baa <NA> 5 e 47 land land <NA>
I want to split only the "here_do" row. Thanks in advance for any kind of help!
我们可以在 base R
中通过替换 'text' 列中 'here_do' 的分隔符来做到这一点,即使用 sub
将其更改为 'here,do',使用 read.csv
和 cbind
读取原始数据集
cbind(df, read.csv(text=sub("(?<=here)_(?=do)", ",", df$text,
perl = TRUE), header=FALSE, col.names = c("first", "sec")))
# var_a var_b text first sec
#1 a 93 foo_bla foo_bla
#2 b 51 here_do here do
#3 c 65 oh_yes oh_yes
#4 d 70 baa baa
#5 e 32 land land
或者如果我们需要 tidyr
解决方案,请使用 extract
library(tidyr)
extract(df, text, into = c("first", "sec"), "(here)_(do)", remove = FALSE)
# var_a var_b text first sec
#1 a 93 foo_bla <NA> <NA>
#2 b 51 here_do here do
#3 c 65 oh_yes <NA> <NA>
#4 d 70 baa <NA> <NA>
#5 e 32 land <NA> <NA>
另一种方法:
cols_to_split = c('here_do')
clean_df <-df %>%
filter(text %in% cols_to_split) %>%
tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>%
bind_rows(filter(df, !text %in% cols_to_split))
# var_a var_b text first sec
#1 b 7 here_do here do
#2 a 26 foo_bla <NA> <NA>
#3 c 23 oh_yes <NA> <NA>
#4 d 2 baa <NA> <NA>
#5 e 67 land <NA> <NA>
如果您需要保留第 'first' 列中的其余行,您可以使用:
clean_df <-df %>%
filter(text %in% cols_to_split) %>%
tidyr::separate(text,into=c("first","sec"),sep="_",remove=F) %>%
bind_rows(filter(df, !text %in% cols_to_split)) %>%
mutate(first = ifelse(is.na(first), as.character(text), first))
# var_a var_b text first sec
#1 b 7 here_do here do
#2 a 26 foo_bla foo_bla <NA>
#3 c 23 oh_yes oh_yes <NA>
#4 d 2 baa baa <NA>
#5 e 67 land land <NA>