【问题标题】:Dataframe manupulation in R - Assign a value to nth row based on row values numbersR 中的数据框操作 - 根据行值编号为第 n 行分配一个值
【发布时间】:2022-12-06 11:10:50
【问题描述】:

我有这个示例数据框“df”:

id <- c(1001, 1002)
col2 <- c(5, 2)
col3 <- c(1, 4)
df <- data.frame(id, col2, col3)

有没有一种简单的方法可以转换此数据框,使新数据框包含相同的列名,但将“1”分配给对应于每个值的第 n 行,并将“0”分配给剩余的槽位?这似乎可行但有些困难。结果表如下 (df_results):

id <- c(rep(1001, 5), rep(1002, 5))
col2 <- c(0,0,0,0,1, 0,1,0,0,0)
col3 <- c(1,0,0,0,0,0,0,0,1,0)
df_results <- data.frame(id, col2, col3)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    是的,您可以使用 R 中 tidyr 包中的 melt() 和 dcast() 函数将数据帧转换为所需格式。

    首先,您可以使用 melt() 函数将数据框转换为“长”格式,其中每一列成为数据框中的新行。然后您可以使用 dcast() 函数将数据框转换回“宽”格式,但这次“长”数据框中的每个值都变成一个新列。

    以下是如何执行此操作的示例:

    library(tidyr)
    
    # Example data frame
    id <- c(1001, 1002)
    col2 <- c(5, 2)
    col3 <- c(1, 4)
    df <- data.frame(id, col2, col3)
    
    # Convert the data frame into a "long" format using melt()
    df_long <- melt(df, id.vars = "id")
    
    # Convert the data frame into a "wide" format using dcast()
    df_wide <- dcast(df_long, id + variable ~ value, fun.aggregate = function(x) 1, value.var = "value")
    
    # Replace the NA values with 0
    df_wide[is.na(df_wide)] <- 0
    
    # Print the resulting data frame
    df_wide
    

    这将为您提供以下数据框:

        id variable 1 2 3 4 5
    1 1001    col2 0 0 0 0 1
    2 1002    col2 0 1 0 0 0
    3 1001    col3 1 0 0 0 0
    4 1002    col3 0 0 0 1 0
    

    【讨论】:

      【解决方案2】:

      你可以 uncount() 使用你的列的并行最大值,然后按 id 分组,检查值是否等于行号:

      library(dplyr)
      library(tidyr)
      
      df %>%
        uncount(pmax(col2, col3)) %>%
        group_by(id) %>%
        mutate(across(starts_with("col"), ~ as.numeric(.x == row_number()))) %>%
        ungroup()
      
      # A tibble: 9 × 3
           id  col2  col3
        <dbl> <dbl> <dbl>
      1  1001     0     1
      2  1001     0     0
      3  1001     0     0
      4  1001     0     0
      5  1001     1     0
      6  1002     0     0
      7  1002     1     0
      8  1002     0     0
      9  1002     0     1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-12
        • 2022-01-16
        • 2013-11-26
        • 2016-12-30
        • 2022-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多