tidyr和dplyr中的R正则表达式?
我有一个由数千行这种类型的代码组成的文件:tidyr和dplyr中的R正则表达式?,r,dplyr,tidyr,R,Dplyr,Tidyr,我有一个由数千行这种类型的代码组成的文件: 1 number entry size1 size2 value size5 value2 my_id1k "AJKJjsdfe76r55"; my_label “1900”; my_idk2 "49354ytu866"; you_digit "some"; my_copy “jkl”; 1 number entry size3 size4 value size6 value2 my_id1k "
1 number entry size1 size2 value size5 value2 my_id1k "AJKJjsdfe76r55"; my_label “1900”; my_idk2 "49354ytu866"; you_digit "some"; my_copy “jkl”;
1 number entry size3 size4 value size6 value2 my_id1k "xyz804"; my_id2k “FI71"; my_id3k “Sk9000”; my_id4k “ldv”;
我想找到一种方法来提取my_id1k
和my_id2k
条目中包含的内容(不带双引号),以及提取其他一些列(我的代码如下)
为此,我想使用tidyr
和dplyr
包中的separate()
和select()
函数,因为它们速度非常快(我关心性能),所以我一直在研究:
但是,我不确定如何在这种异构情况下(我的最后一列长度不同)指定到
和sep
选项,以获得所需的输出。显然,我有一些行的信息比其他行多,因此我想知道如何编写一些高性能的tidyr
和dplyr
代码,以便尽快提取所需的条目
以下是我迄今为止的工作:
> library(dplyr)
> library(tidyr)
> library(data.table)
> x <- fread("myfile_MWE.txt")
> x
V1 V2 V3 V4 V5 V6 V7 V8 V9
1: 1 number entry size1 size2 value size5 value2 my_id1k "AJKJjsdfe76r55"; my_label “1900”; my_idk2 "49354ytu866"; you_digit "some"; my_copy “jkl”;
2: 1 number entry size3 size4 value size6 value2 my_id1k "xyz804"; my_id2k “FI71"; my_id3k “Sk9000”; my_id4k “ldv”;
> y <- separate(x, V9, into = paste("V", 1:15, sep = "_"))
> y
V1 V2 V3 V4 V5 V6 V7 V8 V_1 V_2 V_3 V_4 V_5 V_6 V_7 V_8 V_9 V_10 V_11 V_12 V_13 V_14 V_15
1: 1 number entry size1 size2 value size5 value2 my id1k AJKJjsdfe76r55 my label 1900 my idk2 49354ytu866 you digit some my copy jkl
2: 1 number entry size3 size4 value size6 value2 my id1k xyz804 my id2k FI71 my id3k Sk9000 my id4k ldv NA NA
很明显,在一种情况下我需要V_9
,在另一种情况下我需要V_6
。我期望的结果是:
1 size5 AJKJjsdfe76r55 49354ytu866
1 size6 xyz804 FI71
无论如何,我是否可以以有条件的方式指定
V_9
和V_6
的用法,以便我的代码足够智能,能够识别出我想要下拉my_id1k
和my_id2k
条目中包含的内容,例如通过正则表达式?以下是我使用的数据:
data = structure(list(V1 = c(1L, 1L), V2 = c("number", "number"), V3 = c("entry",
"entry"), V4 = c("size1", "size3"), V5 = c("size2", "size4"),
V6 = c("value", "value"), V7 = c("size5", "size6"), V8 = c("value2",
"value2"), V9 = c("my_id1k \"AJKJjsdfe76r55\"; my_label “1900”; my_idk2 \"49354ytu866\"; you_digit \"some\"; my_copy “jkl”;",
"my_id1k \"xyz804\"; my_id2k “FI71\"; my_id3k “Sk9000”; my_id4k “ldv”;"
)), .Names = c("V1", "V2", "V3", "V4", "V5", "V6", "V7",
"V8", "V9"), class = "data.frame", row.names = c(NA, -2L))
这是代码
library(dplyr)
library(stringi)
library(tidyr)
result =
data %>%
group_by(V9) %>%
do(.$V9 %>%
first %>%
stri_replace_all_fixed("; ", "\n") %>%
read.table(text = ., stringsAsFactors = FALSE) ) %>%
spread(V1, V2) %>%
left_join(data)
以下是我使用的数据:
data = structure(list(V1 = c(1L, 1L), V2 = c("number", "number"), V3 = c("entry",
"entry"), V4 = c("size1", "size3"), V5 = c("size2", "size4"),
V6 = c("value", "value"), V7 = c("size5", "size6"), V8 = c("value2",
"value2"), V9 = c("my_id1k \"AJKJjsdfe76r55\"; my_label “1900”; my_idk2 \"49354ytu866\"; you_digit \"some\"; my_copy “jkl”;",
"my_id1k \"xyz804\"; my_id2k “FI71\"; my_id3k “Sk9000”; my_id4k “ldv”;"
)), .Names = c("V1", "V2", "V3", "V4", "V5", "V6", "V7",
"V8", "V9"), class = "data.frame", row.names = c(NA, -2L))
这是代码
library(dplyr)
library(stringi)
library(tidyr)
result =
data %>%
group_by(V9) %>%
do(.$V9 %>%
first %>%
stri_replace_all_fixed("; ", "\n") %>%
read.table(text = ., stringsAsFactors = FALSE) ) %>%
spread(V1, V2) %>%
left_join(data)
tidyr::extract
比separate
或spread
更好,因为有很多你不在乎的东西
extract(df, V9, c('my_id1k', 'my_id2k'), 'my_id1k .(\\S+).;.*my_id(?:2k|k2) .(\\S+).;')
# V1 V2 V3 V4 V5 V6 V7 V8 my_id1k my_id2k
# 1 1 number entry size1 size2 value size5 value2 AJKJjsdfe76r55 49354ytu866
# 2 1 number entry size3 size4 value size6 value2 xyz804 FI71
注意,这假设my_id2k
和my_idk2
是相同的,正如您在问题中所假设的那样my_id1k
没有变化,因此regex也没有变化。它还假设my_id1k
位于my_id2k
之前。在将其扩展到新数据时,请注意这些可能性,并相应地调整正则表达式
数据:
dftidyr::extract
是比单独
或分散
更好的选择,因为有很多你不在乎的东西
extract(df, V9, c('my_id1k', 'my_id2k'), 'my_id1k .(\\S+).;.*my_id(?:2k|k2) .(\\S+).;')
# V1 V2 V3 V4 V5 V6 V7 V8 my_id1k my_id2k
# 1 1 number entry size1 size2 value size5 value2 AJKJjsdfe76r55 49354ytu866
# 2 1 number entry size3 size4 value size6 value2 xyz804 FI71
注意,这假设my_id2k
和my_idk2
是相同的,正如您在问题中所假设的那样my_id1k
没有变化,因此regex也没有变化。它还假设my_id1k
位于my_id2k
之前。在将其扩展到新数据时,请注意这些可能性,并相应地调整正则表达式
数据:
df谢谢,非常喜欢您的替代解决方案,尤其是stringi
库的使用+1.正确使用do
。另外一个。谢谢,非常喜欢您的替代解决方案,特别是stringi
库的使用+1.正确使用do
。加一,谢谢!整洁的正则表达式。事实上,感谢您指出extract()
函数不熟悉该函数+1.谢谢整洁的正则表达式。事实上,感谢您指出extract()
函数不熟悉该函数+1.