Tengo este tipo de conjunto de datos

DF    
     V1     V2     V3
1.   A      AAA    B
2.   BBB    B      CC
3.   C      BB     CCC

Y me gustaría seleccionar la cadena más larga de DF y ponerla en la nueva columna GANADOR así:

DF    
     V1     V2     V3    WINNER
1.   A      AAA    B     AAA
2.   BBB    B      CC    BBB
3.   C      BB     CCC   CCC

He intentado

mutate( WINNER = select(which.max (c(nchar(V1), nchar(V2), nchar(V3))) 

Pero solo funciona para valores numéricos. Preferiría la solución dplyr.

9
onhalu 26 jun. 2020 a las 15:31

6 respuestas

La mejor respuesta
df$winner <- apply(df,1, function(x) x[which.max(nchar(x))])

df
    V1  V2  V3 winner
1.   A AAA   B    AAA
2. BBB   B  CC    BBB
3.   C  BB CCC    CCC
8
Daniel O 26 jun. 2020 a las 12:36

En caso de empates, la ganadora se basará en la primera aparición:

df$WINNER <- apply(df, 1, function(row) row[which.max(nchar(row))])
7
det 26 jun. 2020 a las 12:35

Puedes usar c_across(). Lo que ponga allí controlará qué columnas se seleccionan.

library(dplyr)

df %>% 
  rowwise() %>% 
  mutate(WINNER = c_across(starts_with("V"))[which.max(nchar(c_across(starts_with("V"))))])

Puede ser un poco más compacto si desea todas las columnas.

df %>% 
  rowwise() %>% 
  mutate(WINNER = c_across()[which.max(nchar(c_across()))])
4
Adam 26 jun. 2020 a las 13:06

Una opción dplyr podría ser.

df %>%
 rowwise() %>%
 mutate(WINNER = get(paste0("V", which.max(nchar(c_across(V1:V3))))))

  V1    V2    V3    WINNER
  <chr> <chr> <chr> <chr> 
1 A     AAA   B     AAA   
2 BBB   B     CC    BBB   
3 C     BB    CCC   CCC 
3
tmfmnk 26 jun. 2020 a las 13:05

Es una pena que max/min en R no tenga el argumento key como en Python, pero uno puede cocinar rápidamente algo similar. Sugeriría algo como esto:

library(tidyverse)


df <- read_table(
  "
  V1     V2     V3
  A      AAA    B
  BBB    B      CC
  C      BB     CCC
  "
)

max_key <- function(vars, fn) {
  vars[which.max(fn(vars))]
}

df %>% 
  rowwise() %>% 
  mutate(
    winner = max_key(c_across(V1:V3), str_length)
  )
#> # A tibble: 3 x 4
#> # Rowwise: 
#>   V1    V2    V3    winner
#>   <chr> <chr> <chr> <chr> 
#> 1 A     AAA   B     AAA   
#> 2 BBB   B     CC    BBB   
#> 3 C     BB    CCC   CCC

Creado en 2020-06-26 por el paquete de reprex (v0.3.0)

2
Peter H. 4 jul. 2020 a las 13:59
df$winner <- 
  Reduce(function(x, y) ifelse(nchar(y) > nchar(x), y, x), df) 

df
#     V1  V2  V3 winner
# 1:   A AAA   B    AAA
# 2: BBB   B  CC    BBB
# 3:   C  BB CCC    CCC
2
IceCreamToucan 26 jun. 2020 a las 12:54