change value to percentage of row in R
Seems a fair case for
df/rowSums(df)
# A B C
# A 0.9000000 0.1000000 0.0000000
# B 0.3333333 0.3333333 0.3333333
# C 0.3333333 0.3333333 0.3333333
If you don't want so many digits after the dot set options(digits = 2)
or use print(df/rowSums(df), digits = 2)
or use round
round(df/rowSums(df), 2)
# A B C
# A 0.90 0.10 0.00
# B 0.33 0.33 0.33
# C 0.33 0.33 0.33
Or as suggested by @akrun
round(prop.table(as.matrix(df1),1),2)
How do I add a new row with percentage change values to an existing dataframe which is in a wide format?
We loop through the columns with lapply
(assuming it is a data.frame
), get the diff
, divide with the first element, round
, paste
with the %
and rbind
rbind(merged, error = lapply(merged, function(x) paste0(100*round(diff(x)/x[1], 2), "%")))
# Jan Feb Mar Apr May Jun
#2017 (A) 1247 1406 1760 2198 1689 2098
#2017 (P) 1259 1187 1649 2090 1682 2056
#error 1% -16% -6% -5% 0% -2%
Or convert to matrix
, get the diff
, divide by the first row, and paste
as above
rbind(merged, error = paste0(100*round(diff(as.matrix(merged))/merged[1,], 2), "%"))
How to convert a row of data to percent? R
Try this:
df[3,-c(1,2)] <- paste0(100*df[3,-c(1,2)],'%')
Month.2020 Jan Feb Mar Apr May Jun Jul
1 1stofMonthCount 4248 4413 4534 4634 4621 4424 3323
2 MonthlyDifference NA 165 121 100 -13 -197 -1101
3 MonthlyPercentChange NA 3.8% 2.7% 2.2% -0.2% -4.3% -24.9%
#Data
df <- structure(list(Month.2020 = c("1stofMonthCount", "MonthlyDifference",
"MonthlyPercentChange"), Jan = c(4248L, NA, NA), Feb = c(4413,
165, 0.038), Mar = c(4534, 121, 0.027), Apr = c(4634, 100, 0.022
), May = c(4621, -13, -0.002), Jun = c(4424, -197, -0.043), Jul = c(3323,
-1101, -0.249)), row.names = c(NA, -3L), class = "data.frame")
R how to calculate 'Percentage of Change' between two rows?
We can use shift
from data.table
. Convert the 'data.frame' to 'data.table' (setDt(df)
), grouped by 'item', we get the "Row" from .I
and create the "Percentage_Change" by dividing the "cumVol" by the lag
of "cumVol" (got by shift
) and multiplying by 100. If needed the grouping column can be removed by assigning (:=
) it to NULL.
library(data.table)
setDT(df)[, list(Row = .I, Percentage_Change=round(cumVol*
(100/shift(cumVol)),2)), .(item)][, item := list(NULL)][]
# Row Percentage_Change
#1: 1 NA
#2: 2 500.00
#3: 3 300.00
#4: 4 NA
#5: 5 32.26
#6: 6 120.00
#7: 7 NA
#8: 8 150.00
NOTE: This gives NA for elements where there are no comparison, instead of the Skip
.
Row-wise percentage with R
Instead of using a for
loop, we can do this with rowSums
df$Fraction <- rowSums(df[2:9], na.rm=TRUE)/8
df$Percent <- 100*df$Fraction
Or as @ColonelBeauvel mentioned, rowMeans
will be more compact and appropriate.
df$Fraction <- rowMeans(df[2:9], na.rm=TRUE)
How can I make a new column and data frame with the percentage change from the start of a particular row in R?
One way using dplyr
:
library(dplyr)
start <- 3
end <- 9
example %>%
slice(start:end) %>%
mutate(wage_change = (wage - first(wage)) * 100/first(wage))
# wage timestamp wage_change
#1 2500 3 0
#2 2400 4 -4
#3 2300 5 -8
#4 2200 6 -12
#5 2700 7 8
#6 2300 8 -8
#7 2900 9 16
Change a table of totals to a table of percentages based on total row
You can loop through the numeric columns with lapply
col_idx <- sapply(a, is.numeric) # find positions of numeric columns
a[, col_idx] <- lapply(a[, col_idx], function(x) {
ifelse(is.na(x), NA, paste0(x / max(x, na.rm = TRUE) * 100, "%"))
})
a
# Color N_Likes N_Dislikes
#1 Blue 50% 25%
#2 Red 40% 50%
#3 Green 10% 25%
#4 Total 100% 100%
Create a loop with mutate() in order to get percentage values by column
mutate(df, across(everything(), ~.x/sum(.x)))
Btw, when you use mutate
, you don't need to refer to the column using $
, it's enough to provide column name.
Create variable for percentage change between two values based on group
If you use lag()
to define your rate, you will end up with "NA" for every b == 3, and the correct value for b == 7 when you group_by "b". Also, c()
is a Primitive function in R and it's best not to use "c" as the name of a variable.
Is this the outcome you're after?
library(tidyverse)
a <- c(3,7,3,7,3,7,3,3,7,3,7,3,7,7)
b <- c("a", "a", "b", "b", "c", "c", "d", "e", "e", "f","f", "g", "g", "h")
d <- c(80, 100, runif(12, min=80, max=100))
df <- data.frame(a,b,d)
df %>% group_by(b) %>%
mutate(rate = 100 * (d - lag(d, default = NA))/lag(d, default = NA))
#> # A tibble: 14 × 4
#> # Groups: b [8]
#> a b d rate
#> <dbl> <chr> <dbl> <dbl>
#> 1 3 a 80 NA
#> 2 7 a 100 25
#> 3 3 b 88.0 NA
#> 4 7 b 91.1 3.54
#> 5 3 c 95.1 NA
#> 6 7 c 82.7 -13.1
#> 7 3 d 92.6 NA
#> 8 3 e 84.1 NA
#> 9 7 e 91.8 9.20
#> 10 3 f 81.9 NA
#> 11 7 f 93.6 14.4
#> 12 3 g 88.7 NA
#> 13 7 g 80.6 -9.11
#> 14 7 h 99.2 NA
Created on 2021-12-20 by the reprex package (v2.0.1)
You can be more flexible with ifelse()
's too, e.g. if you want NA's for cases where you have a single group but zeros for cases where a == 3:
library(tidyverse)
a <- c(3,7,3,7,3,7,3,3,7,3,7,3,7,7)
b <- c("a", "a", "b", "b", "c", "c", "d", "e", "e", "f","f", "g", "g", "h")
d <- c(80, 100, runif(12, min=80, max=100))
df <- data.frame(a,b,d)
df %>% group_by(b) %>%
mutate(group_number = n()) %>%
mutate(rate = ifelse(group_number == 1, NA, ifelse(a == 7, 100 * (d - lag(d, default = NA))/lag(d, default = NA), 0))) %>%
select(-group_number) %>%
ungroup()
#> # A tibble: 14 × 4
#> a b d rate
#> <dbl> <chr> <dbl> <dbl>
#> 1 3 a 80 0
#> 2 7 a 100 25
#> 3 3 b 95.8 0
#> 4 7 b 83.9 -12.5
#> 5 3 c 87.0 0
#> 6 7 c 81.5 -6.26
#> 7 3 d 97.0 NA
#> 8 3 e 99.1 0
#> 9 7 e 82.6 -16.6
#> 10 3 f 82.3 0
#> 11 7 f 96.0 16.7
#> 12 3 g 99.5 0
#> 13 7 g 93.4 -6.09
#> 14 7 h 86.8 NA
Created on 2021-12-20 by the reprex package (v2.0.1)
R Convert a datatable into percentage table columnwise
You can use dplyr::mutate_if()
and scales::percent
:
x %>%
mutate_if(endsWith(names(.),"2021"),function(x) x / sum(x)) %>%
mutate_if(endsWith(names(.),"2021"),scales::percent, accuracy = 0.01)
Output:
class Jan2021 Feb2021
1 A 25.00% 28.57%
2 B 25.00% 42.86%
3 C 50.00% 28.57%
Related Topics
Programmatically Create Tab and Plot in Markdown
Separate a Column into Multiple Columns Using Tidyr::Separate with Sep=""
Plot a Function with Several Arguments in R
Geom_Bar + Geom_Line: with Different Y-Axis Scale
Filtering a Dataframe Showing Only Duplicates
Select N Rows Above and Below Match
Chi Square Test for Each Row in Data Frame
R Bnlearn Eval Inside Function
Writing a Function to Calculate the Mean of Columns in a Dataframe in R
Reconstruct a Categorical Variable from Dummies in R
Map Array of Strings to an Array of Integers
R - Check If String Contains Dates Within Specific Date Range
Convert Byte Encoding to Unicode
Error in Install.Packages:Type =="Both" Cannot Be Used with 'Repos =Null'