R - 按行和列合并数据框

R - Merging dataframe by row and column

我想将数据帧从长格式转换为宽格式,这是一项额外的小任务。我还想将它合并到另一个数据框中。

所以这是我的原始 df,我可以将其转换为宽格式。

  V1   V2 V3
1   A  IIA  1
2   A S1MU  5
3   A  AMU  3
4   C  IIU  6
5   C  IMA  7
6   A S2FU  8
7   B S1MU  9
8   A  IIU 13
9   B S1II  7
10  C S1II  9
11  D  IMA  4
12  A S1II  3

reshape(testframe, idvar = "V1", timevar = "V2", direction = "wide")

   V1 V3.IIA V3.S1MU V3.AMU V3.IIU V3.IMA V3.S2FU V3.S1II
1   A      1       5      3     13     NA       8       3
4   C     NA      NA     NA      6      7      NA       9
7   B     NA       9     NA     NA     NA      NA       7
11  D     NA      NA     NA     NA      4      NA      NA

现在我想将转换后的数据框添加到此数据框中:

  Code IIA S1MU AMU IIU IMA S2FU S1II IFA BIA
1    A  NA   NA  NA  NA  NA   NA   NA  NA  NA
2    B  NA   NA  NA  NA  NA   NA   NA  NA  NA
3    C  NA   NA  NA  NA  NA   NA   NA  NA  NA
4    D  NA   NA  NA  NA  NA   NA   NA  NA  NA

它的列比这个例子需要的多,实际上我有更多,最后两列也会被填满。所以我必须匹配正确的代码和正确的列名。

有什么办法可以做到吗?

测试框架:

structure(list(V1 = c("A", "A", "A", "C", "C", "A", "B", "A", 
"B", "C", "D", "A"), V2 = c("IIA", "S1MU", "AMU", "IIU", "IMA", 
"S2FU", "S1MU", "IIU", "S1II", "S1II", "IMA", "S1II"), V3 = c(1, 
5, 3, 6, 7, 8, 9, 13, 7, 9, 4, 3)), row.names = c(NA, -12L), class = "data.frame")

新框架:

structure(list(Code = c("A", "B", "C", "D"), IIA = c(NA, NA, 
NA, NA), S1MU = c(NA, NA, NA, NA), AMU = c(NA, NA, NA, NA), IIU = c(NA, 
NA, NA, NA), IMA = c(NA, NA, NA, NA), S2FU = c(NA, NA, NA, NA
), S1II = c(NA, NA, NA, NA), IFA = c(NA, NA, NA, NA), BIA = c(NA, 
NA, NA, NA)), row.names = c(NA, -4L), class = "data.frame")

我们可以使用 reshape2data.table 中的 dcast。如果我们需要 'newframe' 中的其他缺失列,只需将那些在输出中找不到但仅在 'newframe' 中找到的列名称分配给 NA,然后将列顺序更改为 [=28] =]

library(data.table)
out <- dcast(setDT(df1), V1 ~ V2, value.var = 'V3')
setnames(out, 'V1', 'Code')
out[, setdiff(names(newframe), names(out)) := NA_real_]
setcolorder(out, names(newframe))

-输出

> out
   Code IIA S1MU AMU IIU IMA S2FU S1II IFA BIA
1:    A   1    5   3  13  NA    8    3  NA  NA
2:    B  NA    9  NA  NA  NA   NA    7  NA  NA
3:    C  NA   NA  NA   6   7   NA    9  NA  NA
4:    D  NA   NA  NA  NA   4   NA   NA  NA  NA

或者如果我们想使用基于索引的base R,创建一个行名称列并使用rownames/column名称进行子集化

out <- xtabs(V3 ~ V1 + V2, df1)
out[out == 0] <- NA
tmp <- as.matrix(`row.names<-`(newframe[-1], newframe$Code))
tmp[row.names(out), colnames(out)] <- out

-输出

> tmp
  IIA S1MU AMU IIU IMA S2FU S1II IFA BIA
A   1    5   3  13  NA    8    3  NA  NA
B  NA    9  NA  NA  NA   NA    7  NA  NA
C  NA   NA  NA   6   7   NA    9  NA  NA
D  NA   NA  NA  NA   4   NA   NA  NA  NA

你可以使用 tidyverse:

library(tidyverse)
testframe %>%
  rename(Code = V1) %>%
  pivot_wider(Code, V2, values_from = V3) %>%
  coalesce(newframe)

  # A tibble: 4 x 10
  Code    IIA  S1MU   AMU   IIU   IMA  S2FU  S1II IFA   BIA  
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl> <lgl>
1 A         1     5     3    13    NA     8     3 NA    NA   
2 C        NA    NA    NA     6     7    NA     9 NA    NA   
3 B        NA     9    NA    NA    NA    NA     7 NA    NA   
4 D        NA    NA    NA    NA     4    NA    NA NA    NA