我有29个数据框,名为Student1到Student 29.这29个数据框中的每一个都包含变量Name,Ethnic和Membership.number,每个都有相应的数字。例如Student1包含Name.1,Ethnic.1和Membership.number.1,Student29包含Name.29等。
我试图通过剥离这些变量名末尾的数字来标准化这些。我是R的新手,但我已经整理了以下代码来尝试自动化。
for (j in 1:29) {
for (i in 1:3) {
oldnames = c(paste('Name', i, sep="."), paste('Nationality', i, sep="."), paste('Membership.number', i, sep="."))
newnames = c("Name", "Nationality", "Membership.number")
names(paste("Student",j,sep=""))[names(paste("Student",j,sep=""))==oldnames[i]]=newnames[i]
}
}
这似乎接近于实现我想要的,并且如果我插入Student1代替粘贴(“Student”,j,sep =“”),那么它对单个数据帧应该起作用,但粘贴(“学生” “,j,sep =”“)由于”赋值目标扩展到非语言对象“,代码似乎失败了。有什么简单的我在这里做错了吗?
答案 0 :(得分:0)
问题是paste()
返回一个字符串,所以你的代码实际上是这样的:
names("Student1")[names("Student1")==oldnames[i]] = newnames[i]
但是,当然,字符串"Student1"
与包含您的数据框的变量Student1
不同,所以这不会让您走得太远。错误消息有点令人困惑,但最终意味着您正在尝试分配给无法分配的内容。
最简单的解决方案是使用函数get()
和assign()
,它们使用字符串命名变量(如字符串"Student1"
),并允许您检索和分配变量。例如,这将重命名Student1
:
dfname = "Student1"
df = get(dfname)
names(df)[names(df)=="Name.1"] = "Name"
assign(dfname, df)
所以,你可以写:
for (j in 1:29) {
oldnames = c(paste('Name', j, sep="."),
paste('Nationality', j, sep="."),
paste('Membership.number', j, sep="."))
newnames = c("Name", "Nationality", "Membership.number")
dfname = paste("Student", j, sep="")
df = get(dfname)
for (i in 1:3) {
names(df)[names(df) == oldnames[i]] = newnames[i]
}
assign(dfname, df)
}
请注意,我已将oldnames
定义修改为使用j
而不是i
,并将仅依赖j
的定义移出内循环。这里需要注意的是,这仅适用于“顶级”(即在R提示下输入)。如果你把它放在一个函数中,那么assign()
变得更加棘手,因为你需要指定 where 你想要分配的变量(在顶层使用其余的全局变量,在函数内)等等。)。
此代码仍可以改进。事实证明,您对oldnames
的定义可以改写为:
oldnames = paste(c("Name","Nationality","Membership.number"), j, sep=".")
这意味着您实际上可以写:
newnames = c("Name","Nationality","Membership.number")
oldnames = paste(newnames, j, sep=".")
您可以更进一步,使用函数match
。此函数在其第二个参数中获取其第一个参数的每个元素的索引,并可用于同时检索oldnames
向量中所有names()
的位置。然后,你甚至不需要内循环:
for (j in 1:29) {
newnames = c("Name","Nationality","Membership.number")
oldnames = paste(newnames, j, sep=".")
dfname = paste("Student", j, sep="")
df = get(dfname)
names(df)[match(oldnames, names(df))] = newnames
assign(dfname, df)
}
使用match
来查找和替换向量中的值是一种非常常见的R技术。
最后,如果数据框中没有任何其他列(所以你真的只想删除所有后缀,包括句点和所有名称末尾的一些数字),那么R中的一个常见技巧是使用sub()
使用正则表达式修改名称:
for (j in 1:29) {
newnames = c("Name","Nationality","Membership.number")
oldnames = paste(newnames, j, sep=".")
dfname = paste("Student", j, sep="")
df = get(dfname)
names(df) = sub("\\.[0-9]+$", "", names(df))
assign(dfname, df)
}
请注意,在R中,正则表达式中的反斜杠需要加倍,因此上面的"\\."
将匹配一个句点。在清理在一堆列名称上包含不需要的前缀和后缀的数据集时,我始终使用这种基于sub
的技术。
快乐的R-ing!