【问题标题】:R Dataframe - Extract Unique rows from columnsR Dataframe - 从列中提取唯一行
【发布时间】:2018-03-30 03:26:18
【问题描述】:

我有一个数据框:

source= c("A", "A", "B") 
target = c("B", "C", "C") 
source_A = c(5, 5, 6) 
target_A = c(6, 7, 7) 
source_B = c(10, 10, 11)
target_B = c(11, 12, 12) 
c = c(0.5, 0.6, 0.7) 
df = data.frame(source, target, source_A, target_A, source_B, target_B, c) 

> df
  source target source_A target_A source_B target_B   c
1      A      B        5        6       10       11 0.5
2      A      C        5        7       10       12 0.6
3      B      C        6        7       11       12 0.7

如何减少此数据框以仅返回唯一源值和目标值的值并返回(忽略 c 列)。

对于值 [A B C]

  id A  B
1  A 5 10
2  B 6 11
3  C 7 12

目前我正在做这样的事情:

df1 <- df[,c("source","source_A", "source_B")]
df2 <- df[,c("target","target_A", "target_B")]

names(df1)[names(df1) == 'source'] <- 'id'
names(df1)[names(df1) == 'source_A'] <- 'A'
names(df1)[names(df1) == 'source_B'] <- 'B'
names(df2)[names(df2) == 'target'] <- 'id'
names(df2)[names(df2) == 'target_A'] <- 'A'
names(df2)[names(df2) == 'target_B'] <- 'B'

df3 <- rbind(df1,df2)
df3[!duplicated(df3$id),]

  id A  B
1  A 5 10
3  B 6 11
5  C 7 12

实际上,我有几十个专栏,所以从长远来看这是不可行的。

我怎样才能更简洁地做到这一点(理想情况下,可以推广到更多列)?

【问题讨论】:

  • 相同idsourcetarget 值总是相同?
  • @LAP 是的(或者我搞砸了......)其他列中 A 的值将始终特定于 A,(即使每列的值不同)。

标签: r join dataframe merge duplicates


【解决方案1】:
library(dplyr)
library(magrittr)

df1 <- subset(df, select = ls(pattern = "source"))
df2 <- subset(df, select = ls(pattern = "target"))

names(df1) <- names(df2)
df <- bind_rows(df1, df2)
df %<>% group_by(target, target_A, target_B) %>% slice(1)

这应该可以,但我不太清楚你想如何概括它。 我不认为这是世界上最优雅的解决方案,但它可以达到目的。希望您打算使用的列可以通过列名字符串模式定位!

【讨论】:

    【解决方案2】:

    这是一个更通用的方法,带有dplyr 函数。您基本上需要将所有内容收集成一个长格式,您可以在其中相应地重命名变量,然后将它们传播回id, A, B

    library(dplyr)
    library(tidyr)
    
    df %>% 
      select(-c) %>% 
      mutate(index = row_number()) %>% 
      gather(key , value, -index) %>%  
      separate(key, c("type", "name"), fill = "right") %>% 
      mutate(name = ifelse(is.na(name), "id", name)) %>% 
      spread(key = name, value = value) %>% 
      select(id, matches("[A-Z]", ignore.case = FALSE)) %>% 
      distinct 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 1970-01-01
      • 2021-06-18
      • 2023-01-28
      • 2019-02-28
      • 1970-01-01
      相关资源
      最近更新 更多