Reputation: 2294
I have the following dataset:
dataloc <- data.frame(id = c("FAS","FAS","FAS","FES","FES"),
gen = c(9,0,0,8,0),
lipd = c(0,2,3,0,5),
stringsAsFactors = FALSE)
So I have two groups: FAS
and FES
. For each group I want to create 3 rows which repeats the non zero value of gen
, a row for each non-zero value of lipd
and a final row that substract lipd
sum from gen
. Each row has a defined name. This is the expected output:
Name Value
First 9
Second 9
Third 9
Added 2
Added 3
Result 4
First 8
Second 8
Third 8
Added 5
Result 3
I can create the result row with this code:
dataloc %>% group_by(id) %>%
summarise(value = sum(gen) - sum(lipd)) %>%
mutate(name = "Result") %>%
select("name","value")
But I kind of stuck in creating n rows based on non-zero values and name them. Any help in R base or tidyverse will be greatly appreciated.
Upvotes: 0
Views: 68
Reputation: 76402
Here is a base R solution. Maybe there are simpler solutions but this one works.
sp <- split(dataloc, dataloc$id)
res <- lapply(sp, function(DF){
i <- which(DF[['gen']] != 0)
j <- which(DF[['lipd']] != 0)
tmp <- rbind(DF[rep(i, 3), ], DF[j, ])
Value <- rowSums(tmp[-1])
Value <- c(Value, Value[1] - sum(DF[j, 'lipd']))
Name <- c("First", "Second", "Third", rep("Added", length(j)), "Result")
id <- rep(DF[['id']][1], length(Name))
data.frame(id, Name, Value)
})
res <- do.call(rbind, res)
row.names(res) <- NULL
res
# id Name Value
#1 FAS First 9
#2 FAS Second 9
#3 FAS Third 9
#4 FAS Added 2
#5 FAS Added 3
#6 FAS Result 4
#7 FES First 8
#8 FES Second 8
#9 FES Third 8
#10 FES Added 5
#11 FES Result 3
Final clean-up.
rm(sp)
Upvotes: 3