我的数据框中有许多眼动追踪数据(更长的固定和更短的扫视),每行对应于眼动仪拍摄的样本(参见专栏timestamp
)。数据逐步进行,包括修复和囊的计数,它们的持续时间以及每个眼球运动是否击中目标(AOI)。这是一个示例:
subj timestamp fix_indx sac_indx eventtype dur AOI_1 AOI_2 AOI_3
MT 409 1 NA Fix 83 NA NA NA
MT 426 1 NA Fix 83 NA NA NA
MT 443 NA 1 Sac 17 NA NA NA
MT 459 NA 1 Sac 17 NA NA NA
MT 476 2 NA Fix 100 0 NA NA
MT 493 2 NA Fix 100 0 NA NA
MT 509 2 NA Fix 100 0 NA NA
MT 526 NA 2 Sac 10 NA NA NA
MT 543 NA NA Unclas 20 NA NA NA
MT 559 3 NA Fix 233 1 NA NA
MT 576 3 NA Fix 233 1 NA NA
MT 593 3 NA Fix 233 1 NA NA
MT 609 NA 3 Sac 11 1 NA NA
MT 626 4 NA Fix 240 NA 1 NA
MT 643 4 NA Fix 240 NA 1 NA
MT 643 4 NA Fix 240 NA 1 NA
MT 659 4 NA Fix 240 NA 1 NA
MT 676 NA 4 Sac 13 NA NA 0
MT 693 5 NA Fix 250 NA NA 1
MT 709 5 NA Fix 250 NA NA 1
MT 726 5 NA Fix 250 NA NA 1
MT 743 5 NA Fix 250 NA NA 1
MT 809 NA 5 Sac 9 NA NA 0
MT 826 6 NA Fix 256 NA NA 0
MT 842 6 NA Fix 256 NA NA 0
MT 859 6 NA Fix 256 NA NA 0
我希望只选择数据集中每个AOI列中的值为0(=外部目标)和1(=内部目标)的部分,即消除任何AOI列所具有的行{{ 1}} (所有列主要是具有1和0的NA)。我有2个条件符合每个AOI列。我使用了NA
函数:
subset
但是,我的数据集中有118个不同的AOI列,因此使用df1<-subset(df,
+ AOI_1 ==0 | AOI_1 ==1 |
+ AOI_2 ==0 | AOI_2 ==1)
意味着最终会得到一个极长的代码字符串。有没有办法更整齐地做到这一点?
我运行AntoniosK示例但是出现错误:
subset
#创建用户ID列(mydfnew$uid <- 1:nrow(mydfnew)
)
uid
> mydfnew %>%
+ select(uid, starts_with("AOI")) %>%
+ filter(complete.cases(.)) %>%
+ select(uid) %>%
+ inner_join(mydfnew, by="uid")
。
由于Error in select_(.data, .dots = lazyeval::lazy_dots(...)) :
object 'uid' not found
和uid
已确认tail(mydfnew)
列已正确创建,因此很奇怪...有人知道这里发生了什么?
答案 0 :(得分:1)
如果您不知道哪些列是AOI列,或者它们之间是否有列,则最好与complete.cases
一起创建AOI列名称的索引,如下所示(在基地R):
AOIcols <- names(df)[grepl("^AOI",names(df))]
df[complete.cases(df[,AOIcols]),]
或来自development version of data.table
的na.omit
cols
参数:
library(data.table) #v1.9.5+
setDT(df)
na.omit(na.omit(df, names(dt)[grepl("^AOI",names(df))]))
在问题中显示的数据中,没有complete.cases
语句为真的行。在@AntoniosK给出的小数据集上应用上述代码可得到相同的结果:
id subj AOI_1 AOI_2
1 1 A 0 1
2 2 A 0 0
另一种dplyr
方法:
library(dplyr)
df %>% select(id, starts_with("AOI")) %>% filter(complete.cases(.)) %>% semi_join(df, by="id")
据我所知,数据集包含眼动追踪数据。由于这样的数据集可能非常大,让我们在一个更大的数据集上尝试不同的方法来模拟问题中的数据集:
# load the need packages
library(dplyr)
library(data.table)
# create a datatable
DT <- data.table(id=seq_len(1e5),
subj=rep(LETTERS[1:10],each=1e4),
dur=rnorm(1e5, mean=70, sd=10),
event=sample(c("fix","sac"), 1e5, TRUE, c(3,1)),
matrix(sample(c(0,0,1,1,1,0,0,1,0,NA), 1e7, TRUE, prob=c(10,10,10,10,10,10,10,10,10,1)), ncol=100))
names(DT) <- gsub("V","AOI_",names(DT))
# create an identical dataframe
DF <- copy(DT)
setDF(DF)
# the benchmarks
library(rbenchmark)
benchmark(replications = 10, order = "elapsed", columns = c("test", "elapsed", "relative"),
jaap = na.omit(DT, names(DT)[grepl("^AOI",names(DT))]),
nico = DF[complete.cases(DF[,5:ncol(DF)]),],
ant1 = DF %>% select(id, starts_with("AOI")) %>% filter(complete.cases(.)) %>% select(id) %>% inner_join(DF, by="id"),
ant2 = {DF %>% select(id, starts_with("AOI")) %>% filter(complete.cases(.)) %>% select(id) -> IDs
DF[IDs$id,]
})
test elapsed relative
1 jaap 0.467 1.000
4 ant2 1.093 2.340
3 ant1 1.191 2.550
2 nico 1.430 3.062
答案 1 :(得分:0)
假设所有AOI列都在最后,您可以使用以下内容选择它们:
my.data[,7:ncol(my.data)]
现在,您可以使用complete.cases
选择那些没有NA的人。
complete.cases(my.data[,7:ncol(my.data)])
答案 2 :(得分:0)
假设您的“AOI”列只有0,1,NA作为值,您可以尝试类似以下(简单)示例。您(提前)唯一需要做的就是为您的行创建一个id并将其作为列:
library(dplyr)
# example dataset
dt = data.frame(id = 1:5,
subj = "A",
AOI_1 = c(0,0,1,NA,NA),
AOI_2 = c(1,0,NA,0,1))
dt
# id subj AOI_1 AOI_2
# 1 1 A 0 1
# 2 2 A 0 0
# 3 3 A 1 NA
# 4 4 A NA 0
# 5 5 A NA 1
dt %>%
select(id, starts_with("AOI")) %>% # keep only id and columns that start with "AOI"
filter(complete.cases(.)) %>% # keep only rows that don't have NAs
select(id) %>% # select the ids of those rows
inner_join(dt, by="id") # join back info for those rows only
# id subj AOI_1 AOI_2
# 1 1 A 0 1
# 2 2 A 0 0
逐步运行示例以查看其工作原理,然后进行所需的任何修改。如果您愿意,可以在流程中创建行ID。
最后不需要内部连接,因为您只需在AOI列中找到没有NA的行,只需选择那些,而不是加入。如果你必须处理数百万行,它会更快:
dt %>%
select(id, starts_with("AOI")) %>%
filter(complete.cases(.)) %>%
select(id) -> IDs
dt[IDs$id,]
@paap每次运行它们时,基准测试似乎都会发生变化(有点)。
我将根据您的数据集发布一些示例:
A)
> # the benchmarks
> system.time(na.omit(dt, names(dt)[grepl("^AOI",names(dt))]))
user system elapsed
0 0 0
>
> system.time(df[complete.cases(df[,3:ncol(df)]),])
user system elapsed
0.02 0.00 0.02
>
> system.time(df %>% select(id, subj, starts_with("AOI")) %>% filter(complete.cases(.)) %>% semi_join(df, by="id"))
user system elapsed
0.02 0.00 0.02
>
> system.time(df %>% select(id, starts_with("AOI")) %>% filter(complete.cases(.)) %>% select(id) %>% inner_join(df, by="id"))
user system elapsed
0.02 0.00 0.01
B)
> system.time(na.omit(dt, names(dt)[grepl("^AOI",names(dt))]))
user system elapsed
0.01 0.00 0.02
>
> system.time(df[complete.cases(df[,3:ncol(df)]),])
user system elapsed
0.02 0.00 0.01
>
> system.time(df %>% select(id, subj, starts_with("AOI")) %>% filter(complete.cases(.)) %>% semi_join(df, by="id"))
user system elapsed
0.02 0.00 0.01
>
> system.time(df %>% select(id, starts_with("AOI")) %>% filter(complete.cases(.)) %>% select(id) %>% inner_join(df, by="id"))
user system elapsed
0.03 0.00 0.04