用另一个data.frame中的值替换data.frame中的值

时间:2014-06-10 17:25:48

标签: r dataframe

我有两个不同尺寸的数据框,

df1 <- data.frame(names= sample(LETTERS[1:10]), duration=sample(0:100, 10))

>df1
   names duration
1      J       97
2      G       57
3      H       53
4      A       23
5      E      100
6      D       90
7      C       73
8      F       60
9      B       37
10     I       67

df2 <- data.frame(names= LETTERS[1:5], names_new=letters[1:5])

> df2
  names names_new
1     A         a
2     B         b
3     C         c
4     D         d
5     E         e

我想在df1中替换与df1$namesdf2$names匹配但使用df2$names_new的值。我想要的输出是:

> df1
   names duration
1      J       97
2      G       57
3      H       53
4      a       23
5      e      100
6      d       90
7      c       73
8      F       60
9      b       37
10     I       67

这是我正在使用的代码,但我想知道是否有更简洁的方法来完成它,没有那么多步骤,

df2[,1] <- as.character(df2[,1])
df2[,2] <- as.character(df2[,2])
df1[,1] <- as.character(df1[,1])    

match(df1[,1], df2[,1]) -> id
which(!is.na(id)==TRUE) -> idx
id[!is.na(id)] -> id

df1[idx,1] <- df2[id,2]

非常感谢

5 个答案:

答案 0 :(得分:5)

以下是来自qdapTools的方法:

library(qdapTools)
df1$names <- df1$names %lc+% df2

%l+%lookup的二元运算符版本。左边是terms,右边是查找表。 +表示任何不兼容的内容都会恢复原状。这是data.table包的包装器,速度非常快。

以下是包含set.seed(1)再现性的输出:

set.seed(1)
df1 <- data.frame(names= sample(LETTERS[1:10]), duration=sample(0:100, 10),stringsAsFactors=F)
df2 <- data.frame(names= LETTERS[1:5], names_new=letters[1:5],stringsAsFactors=F)

library(qdapTools)
df1$names <- df1$names %lc+% df2

df1

##    names duration
## 1      c       20
## 2      d       17
## 3      e       68
## 4      G       37
## 5      b       74
## 6      H       47
## 7      I       98
## 8      F       93
## 9      J       35
## 10     a       71

答案 1 :(得分:2)

df2中的所有姓名是否也在df1?你是否打算将它们作为一个因素?如果是这样,您可能会发现此解决方案很有帮助。

idx <- match(levels(df2$names), levels(df1$names))
levels(df1$names)[idx] <- levels(df2$names_new)

答案 2 :(得分:1)

这有效,但要求namesnames_new是字符,而不是因素。

set.seed(1)
df1 <- data.frame(names= sample(LETTERS[1:10]), duration=sample(0:100, 10),stringsAsFactors=F)
df2 <- data.frame(names= LETTERS[1:5], names_new=letters[1:5],stringsAsFactors=F)


rownames(df1) <- df1$names
df1[df2$name,]$names <- df2$names_new

答案 3 :(得分:0)

使用merge的另一个选项:

transform(merge(df1,df2,all.x=TRUE),
          names=ifelse(is.na(names_new),as.character(names),
                                        as.character(names_new)))

答案 4 :(得分:0)

使用match的另一种方式是(如果df1$namesdf1$names当然是字符)

df1[match(df2$names, df1$names), "names"] <- df2$names_new