Sergei Walankov
Sergei Walankov

Reputation: 135

How do I add a column to a data frame consisting of minimum values from other columns?

How do I add a column to a data frame consisting of the minimum values from other columns? So in this case, to create a third column that will have the values 1, 2 and 2?

df = data.frame(A = 1:3, B = 4:2)

Upvotes: 2

Views: 1811

Answers (5)

Tony
Tony

Reputation: 66

You can call the parallel minimum function with do.call to apply it on all your columns:

df$C <- do.call(pmin, df)

Upvotes: 3

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 9865

You do simply:

df$C <- apply(FUN=min,MARGIN=1,X=df)

Or:

df[, "C"] <- apply(FUN=min,MARGIN=1,X=df)

or:

df["C"] <- apply(FUN=min,MARGIN=1,X=df)

Instead of apply, you could also use data.farme(t(df)), where t transposes df, because sapply would traverse a data frame column-wise applying the given function. So the rows must be made columns. Since t outputs always a matrix, you need to make it a data.frame() again.

df$C <- sapply(data.frame(t(df)), min)

Or one could use the fact that ifelse is vectorized:

df$C <- with(df, ifelse(A<B,A,B))

Or:

df$C <- ifelse(df$A < df$B, df$A, df$B)

matrixStats

# install.packages("matrixStats")

matrixStats::rowMins(as.matrix(df))

According to this SO answer the fastest. apply-type functions use lists and are always quite slow.

Upvotes: 2

Rfanatic
Rfanatic

Reputation: 2282

You can use transform() to add the min column as the output of pmin(a, b) and access the elements of df without indexing:

df <- transform(df, min = pmin(a, b))

or

In data.table

library(data.table)

DT = data.table(a = 1:3, b = 4:2)
DT[,  min := pmin(a, b)]

Upvotes: 1

Homayoun Hamedmoghadam
Homayoun Hamedmoghadam

Reputation: 1267

You can use apply() function to do this. See below.

df$C <- apply(df, 1, min)

The second argument allows you to choose the dimension in which you want min to be applied, in this case 1, applies min to all columns in each row separately.

You can choose specific columns from the dataframe, as follows:

df$newCol <- apply(df[c('A','B')], 1, min)

Upvotes: 4

cazman
cazman

Reputation: 1492

df %>%
  rowwise() %>%
  mutate(C = min(A, B))

# A tibble: 3 × 3
# Rowwise: 
      A     B     C
  <int> <int> <int>
1     1     4     1
2     2     3     2
3     3     2     2

Using input with equal values across rows:

df = data.frame(A = 1:10, B = 11:2)
df %>%
  rowwise() %>%
  mutate(C = min(A, B))

# A tibble: 10 × 3
# Rowwise: 
       A     B     C
   <int> <int> <int>
 1     1    11     1
 2     2    10     2
 3     3     9     3
 4     4     8     4
 5     5     7     5
 6     6     6     6
 7     7     5     5
 8     8     4     4
 9     9     3     3
10    10     2     2

Upvotes: 2

Related Questions