R数据帧,用另一列中的值拆分一列



我在R中有一个数据帧,看起来类似于以下内容:

A    B     C
A    X     1   
A    Y     3   
A    Z     3
A    Z     2

如果所有列都包含因子而不是字符串或整数,我如何将单列"C"转换为与B中的值相对应的多列?

我想要如下所示的内容,无论是否在数据帧中保留B/C列。

A    B    C     X    Y    Z
A    X    1     1    NA   NA
A    Y    3     NA   3    NA
A    Z    3     NA   NA   3
A    Z    2     NA   NA   2

理想情况下,我希望我的最终输出是R中的一个数据帧,因为我打算将它与另一个具有匹配值a值的数据帧合并。

如果这篇帖子重复,我很抱歉,但我没有发现任何地方可以告诉别人在问同样的问题。-谢谢

这里有两种tidyverse方式,我承认它们有点笨拙。它们都使用tidyr::spread来获得宽形状的数据,然后将宽版本绑定回原始版本。

library(tidyr)
library(dplyr)

要使用spread,首先需要对每一行进行某种标识。一个快速的方法是使用tibble::rowid_to_column

df %>%
tibble::rowid_to_column() %>%
spread(key = B, value = C)
#>   rowid A  X  Y  Z
#> 1     1 A  1 NA NA
#> 2     2 A NA  3 NA
#> 3     3 A NA NA  3
#> 4     4 A NA NA  2

您可以这样做,然后将其列绑定到原始数据帧,但您的列将出现无序,并且您将有一个与列A相同的列A1。使用select,可以按正确的顺序选择所需的列。

df %>%
tibble::rowid_to_column() %>%
spread(key = B, value = C) %>%
bind_cols(df) %>%
select(A, B, C, X, Y, Z)
#>   A B C  X  Y  Z
#> 1 A X 1  1 NA NA
#> 2 A Y 3 NA  3 NA
#> 3 A Z 3 NA NA  3
#> 4 A Z 2 NA NA  2

更好的做法是在列绑定的内部执行spread操作,然后删除2个无关列。

bind_cols(
df, 
df %>% tibble::rowid_to_column() %>% spread(key = B, value = C)
) %>%
select(-rowid, -A1)
#>   A B C  X  Y  Z
#> 1 A X 1  1 NA NA
#> 2 A Y 3 NA  3 NA
#> 3 A Z 3 NA NA  3
#> 4 A Z 2 NA NA  2

创建于2018-11-28由reprex包(v0.2.1(

我们可以使用dcastdata.table将'column'C'转换为'wide',然后使用原始数据集转换cbind

library(data.table)
cbind(df1, dcast(setDT(df1), seq_len(nrow(df1))~ B,
value.var = 'C')[, -1, with = FALSE])
#    A B C  X  Y  Z
#1: A X 1  1 NA NA
#2: A Y 3 NA  3 NA
#3: A Z 3 NA NA  3
#4: A Z 2 NA NA  2

数据

df1 <- structure(list(A = c("A", "A", "A", "A"), B = c("X", "Y", "Z", 
"Z"), C = c(1L, 3L, 3L, 2L)), class = "data.frame", row.names = c(NA, 
-4L))

最新更新