R,从另一个表中获取指向列值(更快)

时间:2018-06-18 22:55:02

标签: r pointers dataframe

我有两个数据框。一个包含所有数据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
}

虽然这确实有效,但由于我有一个大数据集,它变得非常慢。我觉得我这样做是愚蠢的。这样做的好方法是什么? 感谢

1 个答案:

答案 0 :(得分:0)

您可以使用sapplylapply - 函数执行此操作。

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