简体   繁体   中英

Reshape R dataframe

I have created the following dataframe object in R

 df<-data.frame("Attribute"<-c("A", "B", "C", "D"), "Name1"<-c(1,2,3,4), 
 "Name2"<-c(2,1,2,1), "Name3"<-c(1,3,2,4)

 names(df)<-c("Attributes", "Name1", "Name2", "Name3")
 df

I would like the following output.

        names attributes''
          1     A D B
          2     B A C
          3     C B
          4     D

I am unable to get a solution for this. Request your help in this regard

Here is a base R solution using stack and by :

# Sample data
df <- data.frame(
    Attribute = c("A", "B", "C", "D"),
    Name1 = c(1,2,3,4),
    Name2 = c(2,1,2,1),
    Name3 = c(1,3,2,4))

df.stacked <- data.frame(stack(df[, -1]), Attribute = df$Attribute);
by(df.stacked, df.stacked$values, function(x) list(unique(x$Attribute)))
#[1] A B D
#Levels: A B C D
#------------------------------------------------------------
#[1] B A C
#Levels: A B C D
#------------------------------------------------------------
#[1] C B
#Levels: A B C D
#------------------------------------------------------------
#[1] D
#Levels: A B C D

Try this

library(dplyr)
library(data.table)
setDT(df)
df2 <- melt(df, id = 1, measure = patterns("Name"), value.name = "names")
df2 %>%
        select(-2) %>%
        group_by(names) %>%
        distinct() %>%
        summarise(attributes = paste(Attributes, collapse = " "))

# output
# A tibble: 4 x 2
  names attributes
  <dbl>      <chr>
1     1      A B D
2     2      B A C
3     3        C B
4     4          D

Here is a solution with base R :

df <- data.frame(Attribute=c("A", "B", "C", "D"), Name1=c(1,2,3,4), Name2=c(2,1,2,1), Name3=c(1,3,2,4))
df
A <- df$Attribute
df <- as.matrix(df[-1])
lapply(1:max(df), function(x) A[apply(df==x, 1, any)])
# > lapply(1:max(df), function(x) A[apply(df==x, 1, any)])
# [[1]]
# [1] A B D
# Levels: A B C D
# 
# [[2]]
# [1] A B C
# Levels: A B C D
# 
# [[3]]
# [1] B C
# Levels: A B C D
# 
# [[4]]
# [1] D
# Levels: A B C D

Here is a solution with data.table :

library("data.table")
df <- data.frame(Attribute=c("A", "B", "C", "D"), Name1=c(1,2,3,4), Name2=c(2,1,2,1), Name3=c(1,3,2,4))
df
A <- df$Attribute
df <- setDT(df[-1])
lapply(1:max(as.matrix(df)), function(a) unique(unlist(sapply(df, function(x) A[x==a]))))
# > lapply(1:max(as.matrix(df)), function(a) unique(unlist(sapply(df, function(x) A[x==a]))))
# [[1]]
# [1] A B D
# Levels: A B C D
# 
# [[2]]
# [1] B A C
# Levels: A B C D
# 
# [[3]]
# [1] C B
# Levels: A B C D
# 
# [[4]]
# [1] D
# Levels: A B C D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM