R - 添加具有几乎相同名称的列并使用正确的列名称保存

标签 r duplicates data.table

我在 R 中有多个大型数据表。某些列名称出现两次,名称几乎重复:除了最后一个字符之外,它们是相同的。

例如:

[1] "Genre_Romance" (correct) 
[2] "Genre_Sciencefiction" (correct) 
[3] "Genre_Sciencefictio" (wrong)
[4] "Genre_Fables" (correct)
[5] "Genre_Fable" (wrong) 

Genre_Romance <- c(1, 0, 1, 0, 1) 
Genre_Sciencefiction <- c(0, 1, 0, 0, 0)
Genre_Sciencefictio <- c(1, 0, 1, 1, 0)
Genre_Fables <- c(0, 0, 1, 0, 0)
Genre_Fable <- c(0, 0, 0, 0, 1)
dt <- data.table(Genre_Romance, Genre_Sciencefiction, Genre_Sciencefictio,   Genre_Fables, Genre_Fable) 

现在我想添加具有几乎相同列名的列值。我想将此总和保存在正确的列名称下,同时删除不正确的列。这里的解决方案是:

dt[,"Genre_Sciencefiction"] <- dt[,2] + dt[, 3]
dt[,"Genre_Fables"] <- dt[,4] + dt[, 5]
dt[,"Genre_Sciencefictio"] <- NULL
dt[,"Genre_Fable"] <- NULL
dt

Genre_Romance    Genre_Sciencefiction   Genre_Fables
    1                   1                   0       
    0                   1                   0       
    1                   1                   1       
    0                   1                   0       
    1                   0                   1   

如您所见,并非每个列名称都有几乎重复的名称(例如“Genre_Romance”)。所以我们就这样保留第一列。

我尝试用 for 循环解决这个问题,逐一比较列名,并使用 substr() 函数比较最长的列名和较短的列名,如果相同则取和。但它无法正常工作,并且对 R 不太友好。

下面的帖子也对我有进一步的帮助,但我不能使用“重复”,因为列名称不完全相同。 how do I search for columns with same name, add the column values and replace these columns with same name by their sum? Using R

提前致谢。

最佳答案

这是一个或多或少的基本 R 解决方案,它依赖 agrep 来查找相似的名称。 agrep 允许基于“广义编辑距离”进行紧密的字符串匹配。

# find groups of similar names
groups <- unique(lapply(names(dt), function(i) agrep(i, names(dt), fixed=TRUE, value=TRUE)))
# choose the final names as those that are longest
finalNames <- sapply(groups, function(i) i[which.max(nchar(i))])

我选择保留与示例匹配的每个组中最长的变量名称,您可以使用 which.min 轻松切换到最短的变量名称,或者您可以根据您的需要进行一些硬编码想要。

接下来,Reduce 被赋予 "+" 运算符,并使用 lapply 馈送匹配组。要计算最大值,请使用 max 代替 "+"。使用 data.table 中的 .SDcols 和 data.frame 选择变量,您可以直接向其提供组向量。

# produce a new data frame
setNames(data.frame(lapply(groups, function(x) Reduce("+", dt[, .SD, .SDcols=x]))),
         finalNames)

@Frank 的评论指出,这可以在 data.table 的新版本(我相信是 1.10+)中进行简化,以避免 .SD, .SDcols

# produce a new data frame
setNames(data.frame(lapply(groups, function(x) Reduce("+", dt[, ..x]))), finalNames)

要使其成为 data.table,只需将 data.frame 替换为 as.data.table 或将输出包装在 setDT 中。


要将最后一行转换为 data.table 解决方案,您可以使用

dtFinal <- setnames(dt[, lapply(groups, function(x) Reduce("+", dt[, .SD, .SDcols=x]))],
                    finalNames)

或者,关注@Frank 的评论

dtFinal <- setnames(dt[, lapply(groups, function(x) Reduce("+", dt[, ..x]))], finalNames)

两者都会返回

dtFinal
   Genre_Romance Genre_Sciencefiction Genre_Fables
1:             1                    1            0
2:             0                    1            0
3:             1                    1            1
4:             0                    1            0
5:             1                    0            1

关于R - 添加具有几乎相同名称的列并使用正确的列名称保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42790351/

相关文章:

java - 使用 rJava 在 R 中显示 Java 控制台输出

r - BLAS DGEMV 错误代码 -6 是什么意思?

ios - 在 NSMutableArray 中搜索对象并删除冗余值的最有效方法

r - data.table 中的条件连接 - 左连接与列选择

r - 为 R 中的各种 ID 跨多行连接值

r - 使用 apply 函数平均数据帧组

R-Project 没有适用于 'meta' 的方法应用于类 "character"的对象

java - 如果集合中有重复值,如何从集合中删除该值

haskell - 类型类实例重新定义

r - 添加具有 NA 值的行