我有这个 data.frame:

df <- data.frame(id = rep(c("one", "two", "three"), each = 10), week.born = NA)
df$week.born[c(5,15,28)] <- c(23,19,24)

df

  id week.born
1    one        NA
2    one        NA
3    one        NA
4    one        NA
5    one        23
6    one        NA
7    one        NA
8    one        NA
9    one        NA
10   one        NA
11   two        NA
12   two        NA
13   two        NA
14   two        NA
15   two        19
16   two        NA
17   two        NA
18   two        NA
19   two        NA
20   two        NA
21 three        NA
22 three        NA
23 three        NA
24 three        NA
25 three        NA
26 three        NA
27 three        NA
28 three        24
29 three        NA
30 three        NA

对于 one,所有 week.born 值都应该是 23
对于 two,所有 week.born 值都应该是 19
对于 one,所有 week.born 值都应该是 24

什么是最好的方法来做到这一点?

最佳答案

我会创建另一个包含映射的 data.frame,然后做一个简单的连接:

require(dplyr)
map <- data.frame(id=c("one","two","three"), new.week.born=c(23,19,24))
left_join(df, map, by="id")

# id week.born new.week.born
# 1    one        NA            23
# 2    one        NA            23
# ...
# 16   two        NA            19
# 17   two        NA            19
# 18   two        NA            19
# 19   two        NA            19
# 20   two        NA            19
# 21 three        NA            24
# 22 three        NA            24
# 23 three        NA            24
# ...

请参阅下面的基准。
library(microbenchmark)
library(dplyr) # v 0.4.1
library(data.table) # v 1.9.5

df <- data.frame(id = rep(c("one", "two", "three"), each = 1e6))
df2 <- copy(df)
map <- data.frame(id=c("one","two","three"), new.week.born=c(23,19,24))

dplyr_join <- function() {
  left_join(df, map, by="id")
}

r_merge <- function() {
  merge(df, map, by="id")
}

data.table_join <- function() {
  setkey(setDT(df2))[map]
}

Unit: milliseconds
              expr         min         lq       mean     median         uq       max neval
      dplyr_join()   409.10635   476.6690   910.6446   489.4573   705.4021  2866.151    10
         r_merge() 41589.32357 47376.0741 55719.1752 50133.0918 54636.3356 83562.931    10
 data.table_join()    94.14621   132.3788   483.4220   225.3309  1051.7916  1416.946    10

关于根据不同列中的值替换 data.frame 列中的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29807032/

10-09 08:48