首页 > 解决方案 > 在R中同时为多个文件添加基于其他列中随机值的新列

问题描述

关于同一个问题的帖子太多了。但我找不到解决方案。我有 140 个单独的文件。每个文件具有相同的列,如下所示。

    taxy      taxx     
1  Alistipes  Roseburia         
2  Alistipes  Clostridium     
3  Alistipes  Clostridium
4  Dorea       Alistipes 
5 Clostridium  Alistipes 
6  Roseburia   Dora

我需要分别基于taxy 和taxx 创建两个新列(otuno)。例如,在taxy 中,有70 多个值。不可能分别为每个值分配数字。我的愿望输出看起来像

taxy      taxx            taxyid   taxxid 
1  Alistipes  Roseburia     1   2
2  Alistipes  Clostridium   1   3
3  Dorea       Alistipes    4   1
4 Clostridium  Alistipes    3   1
5  Roseburia   Dorea        2   4  

如何对 140 个文件一起执行此操作?所有文件都是csv格式

标签: rdataframe

解决方案


我们可以unlist收集数据框中的所有unique值,并基于此为每列添加因子级别并将其转换为整数。

unique_levels <- unique(unlist(df))

df[paste0(names(df), "_id")] <- lapply(df, function(x) 
                                as.integer(factor(x, levels = unique_levels)))
df

#         taxy        taxx taxy_id taxx_id
#1   Alistipes   Roseburia       1       4
#2   Alistipes Clostridium       1       3
#3   Alistipes Clostridium       1       3
#4       Dorea   Alistipes       2       1
#5 Clostridium   Alistipes       3       1
#6   Roseburia       Dorea       4       2

dplyr,我们可以使用mutate_all

library(dplyr)
df %>% mutate_all(list(id = ~as.integer(factor(., levels = unique_levels))))

要将其应用于多个文件,我们可以将上面的代码放在一个函数中

all_files <- list.files("path/of/files", full.names = TRUE)
cols <- c("taxx", "taxy")

apply_fun <- function(df) {
  unique_levels <- unique(unlist(df))
  df[paste0(cols, "_id")] <- lapply(df[cols], function(x) as.integer(factor(x, levels = unique_levels)))
  return(df)
}

lapply并通过使用read.csv或您使用的任何其他方法读取文件,将函数应用于每个文件。

lapply(seq_along(all_files), function(x) 
  write.csv(apply_fun(read.csv(all_files[x])), basename(all_files[x]), row.names = FALSE))

数据

df <- structure(list(taxy = structure(c(1L, 1L, 1L, 3L, 2L, 4L), 
.Label = c("Alistipes", "Clostridium", "Dorea", "Roseburia"), class = "factor"), 
taxx = structure(c(4L, 2L, 2L, 1L, 1L, 3L), .Label = c("Alistipes", "Clostridium", 
"Dorea", "Roseburia"), class = "factor")), class = "data.frame", 
row.names = c("1", "2", "3", "4", "5", "6"))

推荐阅读