我有两个数据帧DF1和DF2:
DF1 <- data.frame(V1 = factor(c("A", "B", "C", "D")),
V2 = factor(c("E", "F", "G", "H")),
Va3 = factor(c("I", "J", "K", "L")),
column = factor(c("M", "N", "O", "P")))
DF2 <- data.frame(N1 = factor(c("x", "V1", "V2", "y", "z", "Va3", "a", "column")),
N2 = factor(c("A", "var1", "random", "R", "Q", "nameofcolumn", "S", "varname4")))
我想根据DF1
中相应单元格的值来更改V1:column
(DF2$N2
)中变量的名称,例如V2
变成random
,而column
变成varname4
。
通常,如果colnames(DF1) <- DF2$N2
中的变量名称与DF1
中的单元格值匹配,我只会使用DF2
;但是这里有这些附加值。如何正确重命名变量?
答案 0 :(得分:2)
在版本1.12.0(于CRAN 2019年1月13日发布)上,data.table的setnames()
函数获得了一个新参数skip_absent
,以跳过old
中的不存在。 setnames()
确实可以与data.frame
和data.table
一起使用。
data.table::setnames(DF1, as.character(DF2$N1), as.character(DF2$N2), skip_absent = TRUE)
DF1
var1 random nameofcolumn varname4 1 A E I M 2 B F J N 3 C G K O 4 D H L P
或者,DF2
中不包含其他列:
DF1 <- data.frame(V1 = factor(c("A", "B", "C", "D")),
V2 = factor(c("E", "F", "G", "H")),
Va3 = factor(c("I", "J", "K", "L")),
column = factor(c("M", "N", "O", "P")),
other = 1:4)
data.table::setnames(DF1, as.character(DF2$N1), as.character(DF2$N2), skip_absent = TRUE)
DF1
var1 random nameofcolumn varname4 other 1 A E I M 1 2 B F J N 2 3 C G K O 3 4 D H L P 4
答案 1 :(得分:1)
您需要使用regex。根据您的实际需要,提取值所基于的模式可能会更改。现在,我正在提取以(^
转换为)varname
和*
开头的“单元”。假设变量名的顺序也是正确的。
注意: :基于第一个版本的问题,其中的列名为varname#
。
colnames(DF1) <- subset(DF2$N2, grepl("^varname*", DF2$N2))
str(DF1)
# 'data.frame': 4 obs. of 4 variables:
# $ varnames1: Factor w/ 4 levels "A","B","C","D": 1 2 3 4
# $ varname2 : Factor w/ 4 levels "E","F","G","H": 1 2 3 4
# $ varname3 : Factor w/ 4 levels "I","J","K","L": 1 2 3 4
# $ varname4 : Factor w/ 4 levels "M","N","O","P": 1 2 3 4
我知道我的模式中的冗余。只需同时包含*
和^
即可为OP提供更多见解。
更新以回答已编辑的问题: 匹配N1
中的值以查找N2
中的列名称:
您可以基于N1
和colnames(DF1)
中的值进行子集设置:
subset(DF2, (N1 %in% colnames(DF1)))
# N1 N2
# 2 V1 var1
# 3 V2 random
# 6 Va3 nameofcolumn
# 8 column varname4
您可以将它们分配为DF1
的列名,如下所示(也可以尝试使用$
运算符):
colnames(DF1) <- DF2$N2[as.numeric(rownames(subset(DF2, (N1 %in% colnames(DF1)))))]
如果两个数据帧中的排序不同,请查看以下线程:Sort one vector based on another
答案 2 :(得分:1)
我们可以只使用match
names(DF1)=DF2$N2[match(names(DF1),DF2$N1)]
DF1
var1 random nameofcolumn varname4
1 A E I M
2 B F J N
3 C G K O
4 D H L P
更新
names(DF1)[which(names(DF1)%in%DF2$N1)]=as.character(DF2$N2[match(names(DF1)[which(names(DF1)%in%DF2$N1)],DF2$N1)])
DF1
var1 random nameofcolumn varname4 somethingelse
1 A E I M M
2 B F J N N
3 C G K O O
4 D H L P P