首页 > 解决方案 > 使用 R 将特定的行值转换为列

问题描述

我有一个类似于下面列出的数据集

v1 <-c('name1','0/0','0/1','1/1','name2','0/0','1/1','name3','0/0','0/1','1/1','name4','0/0','0/1','1/1','name5','0/0','1/1')
v2 <- c(NA,95,3,2,NA,98,2,NA,93,5,2,NA,94,3,3,NA,96,4)
df <- cbind(v1,v2)
df <- as.data.frame(df)
df

看起来像:

v1 v2
名称1 不适用
0/0 95
0/1 3
1/1 2
名称2 不适用
0/0 98
1/1 2
名称3 不适用
0/0 93
0/1 5
1/1 2

如何将数据框重塑为:

名字 0/0 0/1 1/1
名称1 95 3 2
名称2 98 不适用 2
名称3 93 5 2

使用 reshape 我得到的最接近的是:

v1 0/0 0/1 1/1
1 95 . .
2 . 3 .
3 . . 2
4 98 . .
5 . . 2

谢谢!

标签: rdata-manipulationreshape2melt

解决方案


这个怎么运作:

  1. 创建一个id_Group
  2. group_split经过id_Group
  3. 现在你有一个数据框列表my_list
  4. 用于列表中的所有数据lapplypivot_wider
  5. 用于bind_rows将数据框列表合并为一个数据框
  6. 通过随后的一些调整来使用该name列:pivot_longer
library(tidyverse)

my_list <- df %>% 
    mutate(id_Group = cumsum(is.na(v2))) %>% 
    group_split(id_Group) 

df_list <- lapply(1:length(my_list), 
                  function(x) (pivot_wider(my_list[[x]], names_from = v1, values_from = v2)))

bind_rows(df_list) %>% 
    pivot_longer(
        cols = starts_with("name"),
        names_to = "name"
    ) %>% 
    group_by(id_Group) %>% 
    filter(row_number()==1) %>% 
    ungroup() %>% 
    select(name, contains("/"), -id_Group, -value)

  name  `0/0` `0/1` `1/1`
  <chr> <chr> <chr> <chr>
1 name1 95    3     2    
2 name1 98    NA    2    
3 name1 93    5     2    
4 name1 94    3     3    
5 name1 96    NA    4    

推荐阅读