我正在運行一段前面討論過的代碼,該代碼包含150 萬行的大資料,運行需要數小時但尚未完成。我的資料如下所示:
ID London Paris Rome
1 Yes No Yes
2 No No Yes
3 No Yes Yes
4 No Yes No
我想添加一個列,顯示一個 ID 去過的所有城市,以及一個顯示一個 ID 去過的城市數量的列,如下所示:
ID London Paris Rome All Cities Count of Cities travelled
1 Yes No Yes London, Rome 2
2 No No Yes Rome 1
3 No Yes Yes Paris, Rome 2
4 No Yes No Paris 1
我正在運行這段代碼,當我在 100 行資料的樣本上運行它時運行良好:
cities <- c('London', 'Paris', 'Rome')
df %>%
rowwise %>%
mutate(`All Cities` = toString(names(.[, cities])[which(c_across(all_of(cities)) == 'Yes')]),
`Count of Cities travelled` = sum(c_across(all_of(cities)) == 'Yes'))
有什么辦法可以改進這段代碼嗎?還是縮短運行時間?
謝謝!
uj5u.com熱心網友回復:
這是一種tidyverse不使用的方法rowwise(),已知它非常慢。
library(tidyverse)
cities <- c('London', 'Paris', 'Rome')
df <- read.table(header = T, text = "ID London Paris Rome
1 Yes No Yes
2 No No Yes
3 No Yes Yes
4 No Yes No")
df %>%
mutate(across(cities, ~ifelse(.x == "Yes", cur_column(), NA), .names = "{.col}1")) %>%
unite(`All Cities`, ends_with("1"), sep = ", ", na.rm = T) %>%
mutate(`Count of Cities travelled` = str_count(`All Cities`, ",") 1)
ID London Paris Rome All Cities Count of Cities travelled
1 1 Yes No Yes London, Rome 2
2 2 No No Yes Rome 1
3 3 No Yes Yes Paris, Rome 2
4 4 No Yes No Paris 1
uj5u.com熱心網友回復:
基礎 R 中的可能解決方案:
df$Cities <- apply(df, 1, \(x) paste(names(df[-1])[x[-1] == "Yes"], collapse = ", "))
df$N <- apply(df, 1, \(x) sum(x[-1] == "Yes"))
df
#> ID London Paris Rome Cities N
#> 1 1 Yes No Yes London, Rome 2
#> 2 2 No No Yes Rome 1
#> 3 3 No Yes Yes Paris, Rome 2
#> 4 4 No Yes No Paris 1
dplyr和rowwise:_
library(dplyr)
df %>%
rowwise %>%
mutate(Cities = str_c(colnames(df[-1])[c_across(2:4) == "Yes"], collapse = ", "),
N = sum(c_across(2:4) == "Yes")) %>%
ungroup
#> # A tibble: 4 × 6
#> ID London Paris Rome Cities N
#> <int> <chr> <chr> <chr> <chr> <int>
#> 1 1 Yes No Yes London, Rome 2
#> 2 2 No No Yes Rome 1
#> 3 3 No Yes Yes Paris, Rome 2
#> 4 4 No Yes No Paris 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/454807.html
