我一直在尝试以更加细微的方式对数据进行子集化,以避免过多的冗长和冗余。我发现最终要为子集输入复杂的条件,如果要创建数据框的多个子集,这种方法不可行。
数据:
> print(assm)
Speaker V1 POA V2
1 JF01 u tt U
2 JF01 o r a
3 JF01 o t a
4 JF01 a r u
5 JF01 e l i
6 JF01 a j o
7 JF01 e s o
8 JF01 u l i
9 JF01 a j i
10 JF01 i y a
11 JF01 o g i
12 JF01 u m O
13 JF01 u l E
14 JF01 a t o
15 JF01 o r u
16 JF01 a l e
17 JF01 u tt o
18 JF01 o r a
19 JF01 o t a
20 JF01 a r u
21 JF01 e l i
22 JF01 i y O
23 JF01 o r i
24 JF01 i l E
25 JF01 u k o
26 JF01 o n e
27 JF01 a t o
28 JF01 o r u
29 JF01 o r a
30 JF01 u m u
31 JF01 u l a
32 JF01 a t u
33 JF01 u tt o
34 JF01 o r a
35 JF01 o t a
36 JF01 a h e
37 JF01 u r e
38 JF01 o l i
39 JF01 i b o
40 JF01 o l e
41 JF01 e j u
42 JF01 a l e
43 JF01 u tt i
44 JF01 o t a
45 JF01 a r u
46 JF01 e l i
47 JF01 i y U
48 JF01 o r i
49 JF01 i l e
50 JF01 u k o
我使用subset()和data []在以下条件下创建了3个子集:
assm <- subset(assm, V1==“a"| V1=="e"| V1=="E"| V1=="i"| V1=="o"| V1=="O"| V1=="u"| V1=="U", select = Speaker:V2)
assm <- subset(assm, V2==“a”| V2==“e”| V2=="E"| V2=="i"| V2=="o"| V2=="O"| V2=="u"| V2=="U", select = Speaker:V2)
是否有一种更有效的方法(例如,使用正则表达式进行子集设置)来避免所有的硬编码(例如使用变量)? V1和V2的子设置条件是相同的,但是我最终两次输入了内容。
使用非常基本的R,这是我所做的更多子设置:
assm_h <- subset(assm, (V1=="o" & V2=="i")|
(V1=="e" & V2=="i")|
(V1=="u" & V2=="i")|
(V1=="e" & V2=="u")|
(V1=="o" & V2=="u")|
(V1=="u" & V2=="u"))
assm_nh <- subset(assm, (V1=="i" & V2=="O")|
(V1=="i" & V2=="E")|
(V1=="i" & V2=="U")|
(V1=="u" & V2=="O")|
(V1=="u" & V2=="E")|
(V1==“u" & V2=="U"))
我还需要一个子集(assm_neu),其中一个子集所包含的行与assm_h和assm_nh子集所满足的条件(即其余数据)不匹配,该任务需要更艰苦的编码。我的方法需要艰苦的打字和多个步骤。
是否有一种方法可以使此任务更高效,从而使子集不仅返回所要求的内容,还返回不满足条件的数据子集?我已经阅读了多篇有关函数和条件的文章,但是没有哪一篇文章可以帮助我用一个命令提取和创建多个数据集?
先谢谢了。 [编辑:语法]
答案 0 :(得分:0)
不确定到底要获得什么灵活性,但这是我将如何处理另外两个子设置的情况:
library(tibble)
library(dplyr)
library(magrittr)
首先,我将您的数据读为tibble
数据框:
> df <- as.tibble(read.table("temp.txt",header=TRUE))
设置我们要寻找的V1
和V2
的组合:
combos <- c("oi","ei","ui","eu","ou","uu")
现在创建一个临时变量V1V2
:
> df %>% mutate(V1V2=paste0(V1,V2))
# A tibble: 50 x 6
x Speaker V1 POA V2 V1V2
<int> <fct> <fct> <fct> <fct> <chr>
1 1 JF01 u tt U uU
2 2 JF01 o r a oa
3 3 JF01 o t a oa
4 4 JF01 a r u au
5 5 JF01 e l i ei
6 6 JF01 a j o ao
7 7 JF01 e s o eo
8 8 JF01 u l i ui
9 9 JF01 a j i ai
10 10 JF01 i y a ia
# ... with 40 more rows
然后查找满足条件的行(其中只有13条):
> df[z$V1V2 %in% combos,]
# A tibble: 13 x 5
x Speaker V1 POA V2
<int> <fct> <fct> <fct> <fct>
1 5 JF01 e l i
2 8 JF01 u l i
3 11 JF01 o g i
4 15 JF01 o r u
5 21 JF01 e l i
6 23 JF01 o r i
7 28 JF01 o r u
8 30 JF01 u m u
9 38 JF01 o l i
10 41 JF01 e j u
11 43 JF01 u tt i
12 46 JF01 e l i
13 48 JF01 o r i
如果要查找不满足这些条件的行(其中37条),则:
> '%ni%' <- Negate('%in%')
> df[!(z$V1V2 %ni% combos),]
# A tibble: 37 x 5
x Speaker V1 POA V2
<int> <fct> <fct> <fct> <fct>
1 1 JF01 u tt U
2 2 JF01 o r a
3 3 JF01 o t a
4 4 JF01 a r u
5 6 JF01 a j o
6 7 JF01 e s o
7 9 JF01 a j i
8 10 JF01 i y a
9 12 JF01 u m O
10 13 JF01 u l E
# ... with 27 more rows
答案 1 :(得分:0)
考虑使用split
来构建包含 V1 和 V2 的所有组合的数据帧列表。然后,使用do.call
将数据框子集的名称按列表子集,以将所有子集附加在一起:
df_list <- split(assm, assm[c("V1", "V2")])
names(df_list)
# [1] "a.a" "e.a" "i.a" "o.a" "u.a" "a.e" "e.e" "i.e" "o.e" "u.e" "a.E" "e.E" "i.E" "o.E" "u.E" "a.i" "e.i" "i.i" "o.i"
# [20] "u.i" "a.o" "e.o" "i.o" "o.o" "u.o" "a.O" "e.O" "i.O" "o.O" "u.O" "a.u" "e.u" "i.u" "o.u" "u.u" "a.U" "e.U" "i.U"
# [39] "o.U" "u.U"
# CONDITION VECTORS
cond_1 <- c("o.i", "e.i", "u.i", "e.u", "o.u", "u.u")
cond_2 <- c("i.O", "i.E", "i.U", "u.O", "u.E", "u.U")
# FIRST SUBSET
assm_h2 <- do.call(rbind, unname(df_list[cond_1]))
assm_h2 <- with(assm_h2, assm_h2[order(V1, V2),])
# SECOND SUBSET
assm_nh2 <- do.call(rbind, unname(df_list[cond_2]))
assm_nh2 <- with(assm_nh2, assm_nh2[order(V1, V2),])
# THIRD SUBSET (NOT IN EITHER LIST ABOVE)
assm_neu <- do.call(rbind, unname(df_list[!(names(df_list) %in% c(cond_1, cond_2))]))
作为测试,重新排列 V1 和 V2 列后,上述前两个等同于OP的原件:
assm_h <- subset(assm, (V1=="o" & V2=="i")|
(V1=="e" & V2=="i")|
(V1=="u" & V2=="i")|
(V1=="e" & V2=="u")|
(V1=="o" & V2=="u")|
(V1=="u" & V2=="u"))
assm_h <- with(assm_h, assm_h[order(V1, V2),])
identical(assm_h, assm_h2)
# [1] TRUE
assm_nh <- subset(assm, (V1=="i" & V2=="O")|
(V1=="i" & V2=="E")|
(V1=="i" & V2=="U")|
(V1=="u" & V2=="O")|
(V1=="u" & V2=="E")|
(V1=="u" & V2=="U"))
assm_nh <- with(assm_nh, assm_nh[order(V1, V2),])
identical(assm_nh, assm_nh2)
# [1] TRUE
答案 2 :(得分:0)
r2evans正确地指出,GREP是子集数据的最简单方法。感谢@mysteRious建议使用临时列V1V2。我意识到有一种方法可以不用临时列。
这里是一个想法:
attach(assm)
assm_h <- assm[grepl("^oi$|^ei$|^ui$|^eu$|^ou$|^uu$",(paste(assm$V1,assm$V2, sep=""))), ]
assm_nh <- assm[grepl("^iO$|^iE$|^iU$|^uO$|^uE$|^uU$",(paste(assm$V1,assm$V2, sep=""))), ]
assm_neu <- assm[!(grepl("^oi$|^ei$|^ui$|^eu$|^ou$|^uu$",(paste(assm$V1,assm$V2, sep=""))) | (grepl("^iO$|^iE$|^iU$|^uO$|^uE$|^uU$",(paste(assm$V1,assm$V2, sep=""))))), ]
从逻辑上讲,第三种情况是“或非”条件:既不满足两个条件又不需要同时满足两个条件的行。