如何循环遍历数据框列表以在 R 中设置列名?
How to loop through through list of data frames to set column names in R?
我有大量数据框,我想根据第一列和第四行的条件设置列名。请在下面找到我的示例数据:
sample_data<-data.frame(a= c("\"\"","This","Week","1","2", "3", "4", "5", "6" ),b=c("\"\"" , "Last" , "Week" , "(1)" , "(2)" , "(3)" , "(4)" , "(5)" , "(6)" ) ,c=c("\"\"" , "End","2008" , "<1>", "<2>", "<3>", "<4>", "<5>", "<6>" ) ,
d=c("" , "Name" , "" , "Tiger Woods" , "Sergio Garcia" ,"Phil Mickelson" ,"Padraig Harrington", "Vijay Singh" ,"Robert Karlsson") ,e=c("", "Country" , "", "United States" ,"Spain", "United States" , "Ireland" , "Fiji" , "Sweden" ),
f=c("" , "Average" , "Points" ,"11.664" , "7.992" , "6.871" , "6.832" , "6.631" , "5.017" ),f=c("", "Total" ,"Points","466.573" ,"415.591" ,"336.674", "348.431", "358.071", "265.906" ))
another_data<-data.frame(a=c("\"\"","Last", "Week" ,"\"\"","(50)", "(55)","(51)","(52)"),b=c("\"\"" ,"End", "2011","\"\"", "<148>","<70>","<49>","<51>"),c=c("","Name", "\"\"" ,"" ,"Kyle Stanley" , "Kevin Na" ,"Gonzalo Fdez-Castano" ,"Ryo Ishikawa") ,
d=c("","State","\"\"","\"\"", "United States","United States" ,"Spain" ,"Japan"),e=c("\"\"" ,"Country" ,"\"\"","\"\"","United States", "United States" ,"Spain","Japan"),f=c("\"\"","Average" ,"Points" ,"","2.694" ,"2.560","2.544" ,"2.539"))
list_df<-list(sample_data,another_data)
list_df
[[1]]
a b c d e f f.1
1 "" "" ""
2 This Last End Name Country Average Total
3 Week Week 2008 Points Points
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
a b c d e f
1 "" "" "" ""
2 Last End Name State Country Average
3 Week 2011 "" "" "" Points
4 "" "" "" ""
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
所以我想做的是检查第四行是否包含""
。如果是这样,请合并数据框第四行到第一行之间的所有内容。另一方面,如果第四行不包含 ""
,则合并数据框第三行到第一行之间的所有内容。
这是我的试用版:
for (index in 1:length(list_df))
{
if(list_df[[index]][4,1]=="")
{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:4), ]),
sapply(as.data.frame(list_df[[index]][1:4, ]), paste, collapse = ""))
}
else if(list_df[[index]][4,1]!="")
{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:3), ]),
sapply(as.data.frame(list_df[[index]][1:3, ]), paste, collapse = ""))
}
{
return(list_df)
}
}
但这并没有给我想要的输出。只针对第一个条件,不考虑第二个条件。
这是我得到的输出:
list_df
[[1]]
ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
a b c d e f
1
2 Last End Name Country Country Average
3 Week 2011 Points
4
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
然而,想要的输出如下:
list_df
[[1]]
ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
LastWeek End2011 Name State Country AveragePoints
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
我对此很困惑。我不知道为什么其中一个条件被忽略了。谁能帮我解决这个问题?
通常很容易用lapply
遍历列表。你可以试试:
lapply(list_df, function(x) {
if (x[4, 1] == '""') {
names(x) = gsub('"', '', trimws(sapply(x[1:4, ], paste, collapse = "")))
x[-c(1:4), ]
}
else {
names(x) = gsub('"', '', trimws(sapply(x[1:3, ], paste, collapse = "")))
x[-c(1:3), ]
}
})
#[[1]]
# ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
#4 1 (1) <1> Tiger Woods United States 11.664 466.573
#5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
#6 3 (3) <3> Phil Mickelson United States 6.871 336.674
#7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
#8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
#9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
#[[2]]
# LastWeek End2011 Name State Country AveragePoints
#5 (50) <148> Kyle Stanley United States United States 2.694
#6 (55) <70> Kevin Na United States United States 2.560
#7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
#8 (52) <51> Ryo Ishikawa Japan Japan 2.539
就您的 for
循环而言,它不起作用的主要原因是您正在寻找错误的字符。 [4, 1]
处的值是 ""
而不是空字符串(检查 another_data[4, 1] == ''
vs
another_data[4, 1] == '""'
)。如果你改变它,你应该得到想要的输出。但是,我在您的 for
循环中做了一些额外的更改。
- 删除了额外的
else if
条件,因为它不需要。
- 在我的回答中添加了
gsub
以从列名称中删除引号
return(list_df)
没有意义,因为我们已经在 for
循环中更改 list_df
,因此将其删除。
for (index in 1:length(list_df)) {
if(list_df[[index]][4,1] == '""') {
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:4), ]),
gsub('"', '',sapply(as.data.frame(list_df[[index]][1:4, ]),
paste, collapse = "")))
}
else{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:3), ]),
gsub('"', '', sapply(as.data.frame(list_df[[index]][1:3, ]),
paste, collapse = "")))
}
}
我有大量数据框,我想根据第一列和第四行的条件设置列名。请在下面找到我的示例数据:
sample_data<-data.frame(a= c("\"\"","This","Week","1","2", "3", "4", "5", "6" ),b=c("\"\"" , "Last" , "Week" , "(1)" , "(2)" , "(3)" , "(4)" , "(5)" , "(6)" ) ,c=c("\"\"" , "End","2008" , "<1>", "<2>", "<3>", "<4>", "<5>", "<6>" ) ,
d=c("" , "Name" , "" , "Tiger Woods" , "Sergio Garcia" ,"Phil Mickelson" ,"Padraig Harrington", "Vijay Singh" ,"Robert Karlsson") ,e=c("", "Country" , "", "United States" ,"Spain", "United States" , "Ireland" , "Fiji" , "Sweden" ),
f=c("" , "Average" , "Points" ,"11.664" , "7.992" , "6.871" , "6.832" , "6.631" , "5.017" ),f=c("", "Total" ,"Points","466.573" ,"415.591" ,"336.674", "348.431", "358.071", "265.906" ))
another_data<-data.frame(a=c("\"\"","Last", "Week" ,"\"\"","(50)", "(55)","(51)","(52)"),b=c("\"\"" ,"End", "2011","\"\"", "<148>","<70>","<49>","<51>"),c=c("","Name", "\"\"" ,"" ,"Kyle Stanley" , "Kevin Na" ,"Gonzalo Fdez-Castano" ,"Ryo Ishikawa") ,
d=c("","State","\"\"","\"\"", "United States","United States" ,"Spain" ,"Japan"),e=c("\"\"" ,"Country" ,"\"\"","\"\"","United States", "United States" ,"Spain","Japan"),f=c("\"\"","Average" ,"Points" ,"","2.694" ,"2.560","2.544" ,"2.539"))
list_df<-list(sample_data,another_data)
list_df
[[1]]
a b c d e f f.1
1 "" "" ""
2 This Last End Name Country Average Total
3 Week Week 2008 Points Points
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
a b c d e f
1 "" "" "" ""
2 Last End Name State Country Average
3 Week 2011 "" "" "" Points
4 "" "" "" ""
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
所以我想做的是检查第四行是否包含""
。如果是这样,请合并数据框第四行到第一行之间的所有内容。另一方面,如果第四行不包含 ""
,则合并数据框第三行到第一行之间的所有内容。
这是我的试用版:
for (index in 1:length(list_df))
{
if(list_df[[index]][4,1]=="")
{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:4), ]),
sapply(as.data.frame(list_df[[index]][1:4, ]), paste, collapse = ""))
}
else if(list_df[[index]][4,1]!="")
{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:3), ]),
sapply(as.data.frame(list_df[[index]][1:3, ]), paste, collapse = ""))
}
{
return(list_df)
}
}
但这并没有给我想要的输出。只针对第一个条件,不考虑第二个条件。
这是我得到的输出:
list_df
[[1]]
ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
a b c d e f
1
2 Last End Name Country Country Average
3 Week 2011 Points
4
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
然而,想要的输出如下:
list_df
[[1]]
ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
4 1 (1) <1> Tiger Woods United States 11.664 466.573
5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
6 3 (3) <3> Phil Mickelson United States 6.871 336.674
7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
[[2]]
LastWeek End2011 Name State Country AveragePoints
5 (50) <148> Kyle Stanley United States United States 2.694
6 (55) <70> Kevin Na United States United States 2.560
7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
8 (52) <51> Ryo Ishikawa Japan Japan 2.539
我对此很困惑。我不知道为什么其中一个条件被忽略了。谁能帮我解决这个问题?
通常很容易用lapply
遍历列表。你可以试试:
lapply(list_df, function(x) {
if (x[4, 1] == '""') {
names(x) = gsub('"', '', trimws(sapply(x[1:4, ], paste, collapse = "")))
x[-c(1:4), ]
}
else {
names(x) = gsub('"', '', trimws(sapply(x[1:3, ], paste, collapse = "")))
x[-c(1:3), ]
}
})
#[[1]]
# ThisWeek LastWeek End2008 Name Country AveragePoints TotalPoints
#4 1 (1) <1> Tiger Woods United States 11.664 466.573
#5 2 (2) <2> Sergio Garcia Spain 7.992 415.591
#6 3 (3) <3> Phil Mickelson United States 6.871 336.674
#7 4 (4) <4> Padraig Harrington Ireland 6.832 348.431
#8 5 (5) <5> Vijay Singh Fiji 6.631 358.071
#9 6 (6) <6> Robert Karlsson Sweden 5.017 265.906
#[[2]]
# LastWeek End2011 Name State Country AveragePoints
#5 (50) <148> Kyle Stanley United States United States 2.694
#6 (55) <70> Kevin Na United States United States 2.560
#7 (51) <49> Gonzalo Fdez-Castano Spain Spain 2.544
#8 (52) <51> Ryo Ishikawa Japan Japan 2.539
就您的 for
循环而言,它不起作用的主要原因是您正在寻找错误的字符。 [4, 1]
处的值是 ""
而不是空字符串(检查 another_data[4, 1] == ''
vs
another_data[4, 1] == '""'
)。如果你改变它,你应该得到想要的输出。但是,我在您的 for
循环中做了一些额外的更改。
- 删除了额外的
else if
条件,因为它不需要。 - 在我的回答中添加了
gsub
以从列名称中删除引号 return(list_df)
没有意义,因为我们已经在for
循环中更改list_df
,因此将其删除。
for (index in 1:length(list_df)) {
if(list_df[[index]][4,1] == '""') {
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:4), ]),
gsub('"', '',sapply(as.data.frame(list_df[[index]][1:4, ]),
paste, collapse = "")))
}
else{
list_df[[index]]<-setNames(as.data.frame(list_df[[index]][-(1:3), ]),
gsub('"', '', sapply(as.data.frame(list_df[[index]][1:3, ]),
paste, collapse = "")))
}
}