将csv文件与冗余列合并R

aamkag61  于 2022-12-06  发布在  其他
关注(0)|答案(2)|浏览(142)

我有一系列.csv文件,看起来像这样:
a.csv包含

id, a, b, c
1, 10, 0, 0
2, 3, 0 , 0
3, 20, 0, 0

b.csv包含

id, a, b, c
1, 0, 7, 0
2, 0, 9, 0
3, 0, 14, 0

c.csv包含

id, a, b, c
1, 0, 0, 12
2, 0, 0, 8
3, 0, 0, 22

我正在尝试找出读入它们并创建如下所示的 Dataframe 的最有效方法

id, a, b, c
1, 10, 7, 12
2, 3, 9, 8
3, 20, 14, 22

如果有更多的文件具有更多的列和行,最好的方法是什么?tidyverse是首选。

wqsoz72f

wqsoz72f1#

一个base R解,给定文件的对称性。

读取文件
file_names <- list.files(pattern="^[abc]\\.csv")

lis <- sapply(file_names, function(x) list(read.csv(x, header=T)))
lis
$a.csv
  id  a b c
1  1 10 0 0
2  2  3 0 0
3  3 20 0 0

$b.csv
  id a  b c
1  1 0  7 0
2  2 0  9 0
3  3 0 14 0

$c.csv
  id a b  c
1  1 0 0 12
2  2 0 0  8
3  3 0 0 22
合并列
column_names <- c("a","b","c")

cbind( lis[["a.csv"]]["id"], sapply(lis, function(x) rowSums(x[column_names])) )
  id a.csv b.csv c.csv
1  1    10     7    12
2  2     3     9     8
3  3    20    14    22
fquxozlt

fquxozlt2#

这样吧,如果所有多余的列都有零,那么你可以做多,过滤掉零,绑定行,然后做宽。

library(tidyverse)

df_a <- read_table("id a b c
1 10 0 0
2 3 0 0
3 20 0 0")

df_b <- read_table("id a b c
1 0 7 0
2 0 9 0
3 0 14 0")

df_c <- read_table("id a b c
1 0 0 12
2 0 0 8
3 0 0 22")

list(df_a, df_b, df_c)|>
  map(\(d) pivot_longer(d, cols = -id) |>
        filter(value >0)) |>
  bind_rows() |>
  pivot_wider(names_from = name, values_from = value)
#> # A tibble: 3 x 4
#>      id     a     b     c
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1    10     7    12
#> 2     2     3     9     8
#> 3     3    20    14    22

或者更好的是,读入标记0为NA的数据,然后合并 Dataframe 。

df_a <- read_table("id a b c
1 10 0 0
2 3 0 0
3 20 0 0", na = "0")

df_b <- read_table("id a b c
1 0 7 0
2 0 9 0
3 0 14 0", na = "0")

df_c <- read_table("id a b c
1 0 0 12
2 0 0 8
3 0 0 22", na = "0")

coalesce(df_a, df_b, df_c)
#> # A tibble: 3 x 4
#>      id     a     b     c
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1    10     7    12
#> 2     2     3     9     8
#> 3     3    20    14    22

或者,如果可以使用NA读入数据,则可以将0定义为NA:

list(df_a, df_b, df_c) |>
  map(\(d) mutate(d, across(everything(), \(x) ifelse(x == 0, NA, x)))) |>
  reduce(coalesce)
#> # A tibble: 3 x 4
#>      id     a     b     c
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1    10     7    12
#> 2     2     3     9     8
#> 3     3    20    14    22

相关问题