我有两个大的数据帧,A(~25,000行)和B(~275,000行),我需要使用B的内容填充A.我是R的新手,但我之前用Python编写过在pandas中使用for循环和索引可以合理地快速完成这种事情。但是由于在R中使用数据帧索引的循环非常缓慢,因此我编写的方法需要数天才能运行。任何人都知道如何更有效地完成以下任务?
IDs <- c(1,2,3,4,5,6,7,8,9,10)
description1 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
description2 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
description3 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
descriptions <- c('description1','description3','description3','description1','description1','description2','description1','description3','description2','description2')
values <- c(100,200,300,400,500,600,700,800,900,1000)
A <- data.frame(IDs,description1,description2,description3)
B <- data.frame(IDs,descriptions,values)
for (k in 1:nrow(B)){
for (y in 1:nrow(A)){
col_index <- which(names(A) == B[k,2])
column_name <- names(A)[col_index]
ID_A <- A[y,1]
ID_B <- B[k,1]
descriptionA <- A[y,4]
descriptionB <- B[k,2]
if ((ID_A == ID_B) && (descriptionB == column_name)){
A[y,col_index] <- B[k,3]
}
}
}
希望这很简单,我是个白痴。提前谢谢。
答案 0 :(得分:1)
使用reshape
包中的dcast
,您实际上只需reshape2
数据:
dcast(B, IDs ~ descriptions)
IDs description1 description2 description3
1 1 100 NA NA
2 2 NA NA 200
3 3 NA NA 300
4 4 400 NA NA
5 5 500 NA NA
6 6 NA 600 NA
7 7 700 NA NA
8 8 NA NA 800
9 9 NA 900 NA
10 10 NA 1000 NA
答案 1 :(得分:0)
OP表示由于问题规模,处理速度至关重要。
现在,dcast
包以及reshape2
包中提供了data.table
。后者claims:
dcast.data.table
是reshape2::dcast
的更快版本,但是 对于data.table
s。更重要的是,它能够非常好地处理 与内存使用相比,大数据非常有效reshape2::dcast
。
所以,我想知道哪个版本对于data.frame A
中的25.000行的给定问题大小(这是唯一IDs
的数量)和data.frame {中的275.000行会更快。 {1}}。
B
由于n_ID <- 25000L
n_rows_B <- 275000L
n_desc_per_ID <- round(n_rows_B / n_ID)
descriptions <- sprintf("d%02i", seq_len(2L * n_desc_per_ID))
# set.seed() is required for reproducible data
set.seed(123L)
B_DF <- data.frame(IDs = rep(1:n_ID, each = n_desc_per_ID),
d = as.vector(replicate(n_ID, sample(descriptions, n_desc_per_ID))),
v = rpois(n_rows_B, 50))
B_DT <- data.table::data.table(B_DF)
中{1}}中的行数是B
中唯一IDs
的11倍,因此每个A
11个样本会从22个IDs
中随机挑选出来}。请注意,变量名称已缩写,以便以后以宽格式保存屏幕空间。
descriptions
如下所示
B
对于基准测试,使用 IDs d v
1: 1 d07 43
2: 1 d17 36
3: 1 d09 49
4: 1 d21 52
5: 1 d19 50
---
274996: 25000 d09 47
274997: 25000 d18 46
274998: 25000 d17 47
274999: 25000 d14 64
275000: 25000 d02 57
包:
microbenchmark
bm <- microbenchmark::microbenchmark( reshape2 = res1 <- reshape2::dcast(B_DF, IDs ~ d, value.var = "v"), datatable = res2 <- data.table::dcast(B_DT, IDs ~ d, value.var = "v"), times = 100L ) bm
对于给定的问题,大小Unit: milliseconds
expr min lq mean median uq max neval
reshape2 69.57883 72.90287 84.61567 84.45119 86.10444 198.6079 100
datatable 34.66349 36.23196 39.80785 39.67117 40.37139 168.9877 100
确实是dcast.data.table
的两倍。但是,问题大小仍然很小,绝对运行时间可以忽略不计。增加问题大小时,差异会变得更明显。对于reshape2::dcast
中2.7 M行的问题,运行时间为1.2秒至0.4秒。