我有两个不同尺寸的数据框,
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$names
和df2$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]
非常感谢
答案 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)
这有效,但要求names
和names_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$names
和df1$names
当然是字符)
df1[match(df2$names, df1$names), "names"] <- df2$names_new