根据另一个数据框中的值重命名变量

时间:2019-03-17 01:02:41

标签: r dataframe

我有两个数据帧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:columnDF2$N2)中变量的名称,例如V2变成random,而column变成varname4

通常,如果colnames(DF1) <- DF2$N2中的变量名称与DF1中的单元格值匹配,我只会使用DF2;但是这里有这些附加值。如何正确重命名变量?

3 个答案:

答案 0 :(得分:2)

在版本1.12.0(于CRAN 2019年1月13日发布)上,setnames()函数获得了一个新参数skip_absent,以跳过old中的不存在。 setnames()确实可以与data.framedata.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)

您需要使用。根据您的实际需要,提取值所基于的模式可能会更改。现在,我正在提取以(^转换为)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中的列名称:

您可以基于N1colnames(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