1

Assume I have a data frame 100 X 100, here is a small sample of my data

df<-read.table (text=" Id   san1    san2    san3
1   A   A   A
2   A   A   A
3   A   M   M
4   M   A   A
", header=TRUE)

I want to transpose it first. and the calculate the sum of rows and then create two new columns as you can see below

San     1   2   3   4   A   M
san1    A   A   A   M   3   1
san2    A   A   M   A   3   1
san3    A   A   M   A   3   1

I have used df(t) to transpose, and then I have used mutate and rowsums, but it does not work for me.

5 Answers 5

3

Another base R solution:

A <- data.frame(t(df[-1]))
names(A) <- df[,1]
cbind(A, as.data.frame.matrix(t(table(stack(df[-1])))))
     1 2 3 4 A M
san1 A A A M 3 1
san2 A A M A 3 1
san3 A A M A 3 1
Sign up to request clarification or add additional context in comments.

Comments

3

Here is a dplyr solution:

library(dplyr)

df %>% 
  pivot_longer(-Id) %>% 
  pivot_wider(names_from = Id, values_from = value) %>% 
  rename(San = name) %>% 
  mutate(A = rowSums(. == "A"),
         M = rowSums(. == "M"))

Which gives us:

  San   `1`   `2`   `3`   `4`       A     M
  <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 san1  A     A     A     M         3     1
2 san2  A     A     M     A         3     1
3 san3  A     A     M     A         3     1

Comments

2

We can use

library(data.table)
library(tidyr)
data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>%
     mutate(A = rowSums(.[-1] == 'A'), M = rowSums(.[2:5] == 'M'))

-output

#    San 1 2 3 4 A M
#1 san1 A A A M 3 1
#2 san2 A A M A 3 1
#3 san3 A A M A 3 1

6 Comments

@user330 is it the same data on your post
Error: unexpected '=' in: "data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>% mutate(1 ="
A and M hypothetical and i want to use it for any binary data , e.g., 0,1
@user330 in that case, you can just do rowSums(.[2:5]) and rowSums(!.[2:5])
Error: unexpected ')' in: "data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>% mutate(A =rowSums(.[2:5]), M = rowSums(!.[2:5])))"
|
0

Does this do what you want?

a_col <- rowSums(t(df)=="A")
a_col[1] <- "A"
m_col <- rowSums(t(df)=="M")
m_col[1] <- "M"
cbind(t(df), a_col, m_col)

enter image description here

1 Comment

Sorry, it does not work for me as it does not reflect my output. also does not work for large data
0

Another solution that works independently of the A, M and remaining values using table and map_dfr offered via purrr:

library("tidyverse")
df <- read.table (text = " Id   san1    san2    san3
1   A   A   A
2   A   A   A
3   A   M   M
4   M   A   A
", header = TRUE)
df %>%
    pivot_longer(-Id) %>%
    pivot_wider(names_from = Id, values_from = value) %>%
    rename(San = name) %>%
    bind_cols(map_dfr(df, table)[-1, -c(1:nrow(df))])

Results

# A tibble: 3 x 7
  San   `1`   `2`   `3`   `4`   A       M      
  <chr> <chr> <chr> <chr> <chr> <table> <table>
1 san1  A     A     A     M     3       1      
2 san2  A     A     M     A     3       1      
3 san3  A     A     M     A     3       1 

More interesting example

Adding pesky Z value.

df_two <- df
df_two[2,3] <- "Z"

sum_those_letters <- function(.data, nice_id_col = Id, pretty_name = "San") {
    .data %>%
        pivot_longer(-{{nice_id_col}}) %>%
        pivot_wider(names_from = {{nice_id_col}}, values_from = value) %>%
        rename(pretty_name = name) %>%
        bind_cols(map_dfr(df_two, table)[-1, -c(1:nrow(.data))])
}

Results

sum_those_letters(df_two, Id)

# A tibble: 3 x 8
  San   `1`   `2`   `3`   `4`   A       M       Z      
  <chr> <chr> <chr> <chr> <chr> <table> <table> <table>
1 san1  A     A     A     M     3       1       NA     
2 san2  A     Z     M     A     2       1        1     
3 san3  A     A     M     A     3       1       NA 

2 Comments

Sorry, it does not work for my data, I did not get sums in my cloumns
@user330 I've included the data, it's from your post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.