R lapply 跨数据框列表的函数
R lapply function across a list of data frames
这个问题论坛上有类似的解决办法;但是我无法使代码正常工作,需要提出一个新问题。
我将大约 20 个非常宽的 csv 文件导入到全局环境中。我需要能够删除特殊字符并更改从 CSV 中提取的列的名称。
这里是两个数据框的示例代码,然后生成一个列表:
df1 <- data.frame("ï.ID" = 1, "Q.1" = 2, Q1.1 = 3)
df2 <- data.frame("ï.ID." = 2, "Q.1a" = 3, Q1.1 = 4)
Qs <- data.frame("Original.Question" = "Q1a", "Question" = "Q.1")
dflist <- lapply(ls(), function(x) if (class(get(x)) == "data.frame") get(x))
当我导入文件时,在 ID 列前面有一个 BOM 字符 i,上面有两个点。我在单个数据框中使用以下代码,因为我尝试在 dflist 上使用 lappy 都失败了。
names(df1) <- gsub("[^A-Za-z0-9]", "", names(df1))
我想做的第二件事是重命名 csv 中的列。同样,我似乎没有正确的功能来让它工作。我要修改以遍历所有数据帧的具体代码是:
names(df1)[names(df1)
%in% Qs$Original.Question] = Qs$Question[match(names(df1)[names(df1)
%in% Qs$Original.Question], Qs$Original.Question)]
这允许我使用 CSV 重命名所有问题列,因为在将数据框合并为单个数据框之前必须重命名它们。同样,我似乎无法正确应用 lapply 函数。
很抱歉需要再次提出类似的问题。我尝试过改编代码,但惨遭失败。
您可以根据名称中的模式获取数据框。在示例中,您有 df1
、df2
,您可以使用 'df'
后跟数字的模式获取列表中的所有数据帧。使用 mget
将它们放入列表中,使用 lapply
覆盖它们并重命名列。
list_df <- mget(ls(pattern = 'df\d+'))
dflist <- lapply(list_df, function(x)
{names(x) <- gsub("[^A-Za-z0-9]", "", names(x));x})
此外,您可能对 R's read.csv prepending 1st column name with junk text 感兴趣,它避免在第一列中获取 BOM 字符。
您首先需要过滤掉 NULL
个对象。你可以这样做:
dflist <- Filter(Negate(is.null), dflist)
lapply(dflist, function(x) setNames(x,gsub("[^A-Za-z0-9]", "", names(x))))
[[1]]
sex school daysmissed
1 M north 5
2 F north 1
3 M central 2
4 M south 0
5 F south 7
6 F south 1
7 F central 3
8 M north 2
9 M north 4
10 F south 15
[[2]]
ID Q1 Q11
1 1 2 3
[[3]]
ID Q1a Q11
1 2 3 4
[[4]]
OriginalQuestion Question
1 Q1a Q.1
这个问题论坛上有类似的解决办法;但是我无法使代码正常工作,需要提出一个新问题。
我将大约 20 个非常宽的 csv 文件导入到全局环境中。我需要能够删除特殊字符并更改从 CSV 中提取的列的名称。
这里是两个数据框的示例代码,然后生成一个列表:
df1 <- data.frame("ï.ID" = 1, "Q.1" = 2, Q1.1 = 3)
df2 <- data.frame("ï.ID." = 2, "Q.1a" = 3, Q1.1 = 4)
Qs <- data.frame("Original.Question" = "Q1a", "Question" = "Q.1")
dflist <- lapply(ls(), function(x) if (class(get(x)) == "data.frame") get(x))
当我导入文件时,在 ID 列前面有一个 BOM 字符 i,上面有两个点。我在单个数据框中使用以下代码,因为我尝试在 dflist 上使用 lappy 都失败了。
names(df1) <- gsub("[^A-Za-z0-9]", "", names(df1))
我想做的第二件事是重命名 csv 中的列。同样,我似乎没有正确的功能来让它工作。我要修改以遍历所有数据帧的具体代码是:
names(df1)[names(df1)
%in% Qs$Original.Question] = Qs$Question[match(names(df1)[names(df1)
%in% Qs$Original.Question], Qs$Original.Question)]
这允许我使用 CSV 重命名所有问题列,因为在将数据框合并为单个数据框之前必须重命名它们。同样,我似乎无法正确应用 lapply 函数。
很抱歉需要再次提出类似的问题。我尝试过改编代码,但惨遭失败。
您可以根据名称中的模式获取数据框。在示例中,您有 df1
、df2
,您可以使用 'df'
后跟数字的模式获取列表中的所有数据帧。使用 mget
将它们放入列表中,使用 lapply
覆盖它们并重命名列。
list_df <- mget(ls(pattern = 'df\d+'))
dflist <- lapply(list_df, function(x)
{names(x) <- gsub("[^A-Za-z0-9]", "", names(x));x})
此外,您可能对 R's read.csv prepending 1st column name with junk text 感兴趣,它避免在第一列中获取 BOM 字符。
您首先需要过滤掉 NULL
个对象。你可以这样做:
dflist <- Filter(Negate(is.null), dflist)
lapply(dflist, function(x) setNames(x,gsub("[^A-Za-z0-9]", "", names(x))))
[[1]]
sex school daysmissed
1 M north 5
2 F north 1
3 M central 2
4 M south 0
5 F south 7
6 F south 1
7 F central 3
8 M north 2
9 M north 4
10 F south 15
[[2]]
ID Q1 Q11
1 1 2 3
[[3]]
ID Q1a Q11
1 2 3 4
[[4]]
OriginalQuestion Question
1 Q1a Q.1