【问题标题】:dplyr::mutate new columns based on a second (filtered) dataframedplyr::mutate 基于第二个(过滤的)数据帧的新列
【发布时间】:2021-03-13 21:27:38
【问题描述】:

我有 2 个数据框:

df1:

a
s1
s2
s3
s4

df2:

a    b
s1    w
s1    x
s4    y
s2    z
s4    x

我想将与 df2$b (w, x, y, z) 中的唯一值一样多的列附加到 df1,如果 df2$a 有一行关联,则为每个 df1$a 和新列添加 1他们。这解释起来很麻烦,也许显示所需的输出更好:

a    w    x    y    z
s1    1    1    0    0
s2    0    0    0    1
s3    0    0    0    0
s4    0    1    1    0

我试过了

for (col_name in unique(df2$b)){
  df1 %<>%
    mutate(!!as.character(col_name) := ifelse(col_name %in% filter(df2,
                                                                   a == df1$a)$b,
                                          yes = 1,
                                          no = 0))
}

但这不起作用,我猜问题出在

a == df1$a

bit,但我不知道哪个是正确的语法。任何帮助表示赞赏!

【问题讨论】:

  • 你可以使用table(df2)

标签: r filter tidyverse dplyr


【解决方案1】:

另一个dplyrtidyr 解决方案。

library(dplyr)
library(tidyr)

df3 <- df2 %>%
  mutate(value = 1) %>%
  complete(a = df1$a, b) %>%
  spread(b, value, fill = 0)

df4 <- df1 %>%
  left_join(df3, by = "a")

数据

df1 <- tibble(
  a = paste0("s", 1:4)
)

df2 <- read.table(text = "
a    b
s1    w
s1    x
s4    y
s2    z
s4    x",
                header = TRUE)

【讨论】:

    【解决方案2】:

    我们可以在base R 中使用table(假设我们想要'df1' 中'a' 列的所有值的行,将'df2' 的'a' 列转换为factor 与@ 987654324@ 指定为 'df1' 中的 'a' 的 unique values

    table(transform(df2, a = factor(a, levels = unique(df1$a))))
    

    -输出

    # b
    #a    w x y z
    #  s1 1 1 0 0
    #  s2 0 0 0 1
    #  s3 0 0 0 0
    #  s4 0 1 1 0
    

    数据

    df1 <- structure(list(a = c("s1", "s2", "s3", "s4")), class = "data.frame",
    row.names = c(NA, 
    -4L))
    
    df2 <- structure(list(a = c("s1", "s1", "s4", "s2", "s4"), b = c("w", 
    "x", "y", "z", "x")), class = "data.frame", row.names = c(NA, 
    -5L))
    

    【讨论】:

    • 这可行,但它返回一个表格而不是一个数据框
    • @Miguel 我会用as.data.frame.matrix(table(transform(df2, a = factor(a, levels = unique(df1$a)))))包装
    • 可以,谢谢,但我已经接受了包含 dplyr 的其他答案
    • @Miguel 没关系。您的问题也与 dplyr 有关,这是有道理的。谢谢
    【解决方案3】:

    试试这个:

    library(dplyr)
    library(tidyr)
    #Code
    newdf <- df1 %>% full_join(df2) %>%
      mutate(val=ifelse(!is.na(b),1,NA),
             b=ifelse(is.na(b),'Emp',b)) %>%
      pivot_wider(names_from = b,values_from=val,
                  values_fill=0,names_sort = T) %>%
      select(-Emp)
    

    输出:

    # A tibble: 4 x 5
      a         w     x     y     z
      <chr> <dbl> <dbl> <dbl> <dbl>
    1 s1        1     1     0     0
    2 s2        0     0     0     1
    3 s3        0     0     0     0
    4 s4        0     1     1     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-22
      相关资源
      最近更新 更多