我想在同一sample_id
列中使用State
字符串标记多个no
的样本(E
collumn)。
我的df
数据框输入:
no sample_id State
chr1-15984544-15996851-0n NE001788 0n
chr1-15984544-15996851-0n NE001788 1n
chr1-15984544-15996851-0n NE001836 0n
chr1-15984544-15996851-0n NE002026 0n
chr1-15984544-15996851-0n NE001413 0n
chr1-15984544-15996851-0n NE001438 0n
我的预期output
:
no sample_id State
chr1-15984544-15996851-0n NE001788 E
chr1-15984544-15996851-0n NE001836 0n
chr1-15984544-15996851-0n NE002026 0n
chr1-15984544-15996851-0n NE001413 0n
chr1-15984544-15996851-0n NE001438 0n
示例NE001788
标有E,因为它在同一个State
字符串中有两种不同的状态(no
)。
我使用下面的代码来处理小数据帧:
df <- read.table(text= 'no sample_id State
chr1-15984544-15996851-0n NE001788 0n
chr1-15984544-15996851-0n NE001788 1n
chr1-15984544-15996851-0n NE001836 0n
chr1-15984544-15996851-0n NE002026 0n
chr1-15984544-15996851-0n NE001413 0n
chr1-15984544-15996851-0n NE001438 0n',header=TRUE)
library(plyr)
output <- unique(ddply(df,.(no,sample_id),mutate,State=if(length(unique(State))>1) {"E"} else State))
工作正常。但是,我现在有一个大型数据框(超过700k行)。在这个大型数据帧中,我收到内存错误:cannot allocate vector of size 75kb
。
我在这里要求替代方案达到相同的结果,没有内存突破。
非常感谢。
答案 0 :(得分:3)
试试data.table
。我没有对此代码进行基准测试,但它肯定比plyr
library(data.table)
df <- setDT(df)[, lapply(.SD, function(x) ifelse(.N > 1, "E", as.character(x))), by = c("no", "sample_id"), .SDcols = "State"]
## no sample_id State
## 1: chr1-15984544-15996851-0n NE001788 E
## 2: chr1-15984544-15996851-0n NE001836 0n
## 3: chr1-15984544-15996851-0n NE002026 0n
## 4: chr1-15984544-15996851-0n NE001413 0n
## 5: chr1-15984544-15996851-0n NE001438 0n
更好的选择是首先使State
成为一个字符(如果它还没有),以避免在每个组中执行as.character
,然后进行子集化。像
setDT(df)[, State := as.character(State)]
df <- df[, lapply(.SD, function(x) ifelse(.N > 1, "E", x)), by = c("no", "sample_id"), .SDcols = "State"]
答案 1 :(得分:1)
这里有dyplr
代码:
dd %>%
mutate(State = as.character(State)) %>%
group_by(no, sample_id) %>%
summarize(State = ifelse(length(unique(State)) > 1, "E", State))
最有可能的情况是,使用dplyr
会比plyr
更快,但我不知道它在内存使用方面的比较,因为这似乎是您案例中的瓶颈。
请注意,我在操作之前将State
转换为字符,因为如果您从问题中读取数据,那么它将是factor
s。如果实际上它们是角色,你当然可以跳过它。
注意:我使用length(unique(State)) > 1
来涵盖(假设)no
,sample_id
和State
中的条目在多行中都相同的情况。根据您的说明,在这种情况下,您不希望将E
分配给State
,但不清楚您的数据中是否可以存在此类情况。如果没有,您可以将length(unique(State)) > 1
替换为n() > 1
。