簡體   English   中英

基於兩列修改R數據幀

[英]Modying R data frame based on two columns

我正在嘗試修改以下R數據幀:

Column1         Column2            Value1            Value2
Parent1         Child1             3                 12
Parent1         Child2             4                 12
Parent1         Child3             5                 12
Parent2         Child4             2                 9
Parent2         Child5             6                 9
Parent2         Child6             1                 9

我想將“ Parent”項放置在“ Child”項上方,並將值從“ Value2”移到“ Value1”。 新數據框將如下所示:

Column2         Value1            
Parent1         12
   Child1       3                
   Child2       4                
   Child3       5                 
Parent2         9
   Child4       2                 
   Child5       6                 
   Child6       1          

可以使用dplyr完成嗎? 另外,有沒有一種方法可以在“孩子”條目中添加任何額外的空格?

感謝您的見解。

准備數據

library(tidyverse)
data <- read_delim(
    "Column1         Column2            Value1            Value2
Parent1         Child1             3                 12
Parent1         Child2             4                 12
Parent1         Child3             5                 12
Parent2         Child4             2                 9
Parent2         Child5             6                 9
Parent2         Child6             1                 9",delim = " "
) %>%
    mutate_all(~str_remove_all(.x," "))
colnames(data) <- str_remove_all(colnames(data)," ")

使用tidyr::nest()來“清除”數據,以便我們可以tidyr::nest()迭代數據。

nested_data <- data %>%
    group_by(Column1,Value2) %>%
    nest()
> nested_data
# A tibble: 2 x 3
  Column1 Value2 data            
  <chr>   <chr>  <list>          
1 Parent1 12     <tibble [3 x 2]>
2 Parent2 9      <tibble [3 x 2]>

然后使用pmap_df()構造所需的輸出。

pmap_df(nested_data,function(...){
    values = list(...)
    bind_rows(
        tibble(
            Column2 = values$Column1,
            Value1 = values$Value2
        )
        ,
        values$data %>%
            mutate(Column2 = paste0("  ",Column2)) # add white space
    )
})

# A tibble: 8 x 2
  Column2    Value1
  <chr>      <chr> 
1 Parent1    12    
2 "  Child1" 3     
3 "  Child2" 4     
4 "  Child3" 5     
5 Parent2    9     
6 "  Child4" 2     
7 "  Child5" 6     
8 "  Child6" 1 

這是dplyr的另一種方式。 如果需要,可以刪除group列,並使arrange邏輯更健壯。 --

df %>% 
  mutate(group = group_indices(., Column1)) %>%
  {bind_rows(
    distinct(., Column = Column1, Value = Value2, group),
    select(., Column = Column2, Value = Value1, group) %>% 
      mutate(Column = paste0("   ", Column))
  )} %>% 
  arrange(group, desc(Column))

# A tibble: 8 x 3
  Column      Value group
  <chr>       <int> <int>
1 Parent1        12     1
2 "   Child3"     5     1
3 "   Child2"     4     1
4 "   Child1"     3     1
5 Parent2         9     2
6 "   Child6"     1     2
7 "   Child5"     6     2
8 "   Child4"     2     2

數據-

df <- structure(list(Column1 = c("Parent1", "Parent1", "Parent1", "Parent2", 
"Parent2", "Parent2"), Column2 = c("Child1", "Child2", "Child3", 
"Child4", "Child5", "Child6"), Value1 = c(3L, 4L, 5L, 2L, 6L, 
1L), Value2 = c(12L, 12L, 12L, 9L, 9L, 9L)), .Names = c("Column1", 
"Column2", "Value1", "Value2"), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

這是一個data.table解決方案:

library(data.table)

DT[, GRP := .GRP, by = Column1]
DT[, ID := .I]

DT_bind <- rbindlist(list(DT[, .(Value1 = first(Value2), .GRP, ID = NA_integer_), by = .(Column2 = Column1)]
               ,DT[, .(Column2, Value1, GRP, ID)]))

setorder(DT_bind, GRP, ID)

DT_bind[, .(Column2, Value1)]

   Column2 Value1
1: Parent1     12
2:  Child1      3
3:  Child2      4
4:  Child3      5
5: Parent2      9
6:  Child4      2
7:  Child5      6
8:  Child6      1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM