我有两个数据框。一个包含所有数据A,另一个包含A的唯一标识符和A列的名称。我试图在A的基础上添加一个B指向的列。换句话说,我需要从B指向的数据中获取数据。 例如
A<-airquality
B<-data.frame(Month=unique(A$Month),col=c("Ozone","Solar.R", "Wind", "wind","Solar.R"))
这会给我以下
> head(A)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
> B
Month col
1 5 Ozone
2 6 Solar.R
3 7 Wind
4 8 wind
5 9 Solar.R
结果应该是
> head(A)
Ozone Solar.R Wind Temp Month Day ADDED
1 41 190 7.4 67 5 1 41
2 36 118 8.0 72 5 2 36
3 12 149 12.6 74 5 3 12
4 18 313 11.5 62 5 4 18
5 NA NA 14.3 56 5 5 NA
6 28 NA 14.9 66 5 6 28
> tail(A)
Ozone Solar.R Wind Temp Month Day ADDED
148 14 20 16.6 63 9 25 20
149 30 193 6.9 70 9 26 193
150 NA 145 13.2 77 9 27 145
151 14 191 14.3 75 9 28 191
152 18 131 8.0 76 9 29 131
153 20 223 11.5 68 9 30 223
我能做到的唯一方法是
for(i in 1:nrow(B))
{
j<-A$Month==B$Month[i]
k<-subset(A, select=B$col[i])[j,]
A$ADDED[j]<-k
}
虽然这确实有效,但由于我有一个大数据集,它变得非常慢。我觉得我这样做是愚蠢的。这样做的好方法是什么? 感谢
答案 0 :(得分:0)
您可以使用sapply
或lapply
- 函数执行此操作。
ADDED <- sapply(1:nrow(B), function(i){
A[A$Month==B$Month[i], (B$col[i])]
})
A$ADDED <- unlist(ADDED)
对于部分匹配,您必须过滤数据,以仅获取B具有值的行,然后分配值。但是我们必须为ADDED列的所有行分配一个值;在这种情况下NA。
A$ADDED = NA
A[A$Month %in% B$Month,]$ADDED <- unlist(ADDED)
与for-loop相比,这已经只占了1/3的时间。
appl <- function(){
ADDED <- sapply(1:nrow(B), function(i){
A[A$Month==B$Month[i], (B$col[i])]
})
A$ADDED1 <- unlist(ADDED)
}
lappl <- function(){
ADDED <- lapply(1:nrow(B), function(i){
A[A$Month==B$Month[i], (B$col[i])]
})
A$ADDED1 <- unlist(ADDED)
}
forlo <- function(){
for(i in 1:nrow(B)) {
j<-A$Month==B$Month[i]
k<-subset(A, select=B$col[i])[j,]
A$ADDED[j]<-k
}
}
library(microbenchmark)
mc <- microbenchmark(times = 1000,
sapply = appl(),
lapply = lappl(),
forloop = forlo()
)
mc
Unit: microseconds expr min lq mean median uq max neval cld sapply 337.478 359.2125 378.6964 369.7775 385.474 2324.913 1000 a lapply 319.367 340.7990 366.8448 349.2510 362.532 9051.828 1000 a forloop 964.136 1013.6415 1074.5584 1032.5070 1059.825 5116.802 1000 b