いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【R】重複を削除したい

・お題:ベクトルの要素の重複を削除したり、data.frameの行の重複を削除する方法をいつも忘れるので、メモしておきたい。

# ライブラリ読み込み

library(tidyverse)

 

# ベクトルの要素の重複を何とかする。

# ベクトル作成

test <- c("A", "A", "A", "B", "B", "B", "C", "C", "C")
test

[1] "A" "A" "A" "B" "B" "B" "C" "C" "C"

 

# 被っているのを削る。

unique(test)

[1] "A" "B" "C"

 

# 例えば、ベクトルの要素に名前がついていると、unique関数だと名前が消える。

names(test) <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
unique(test)

[1] "A" "B" "C"

 

# duplicated関数でどれがダブっているか判定して、ダブっていないものを取り出すことにする。最初に出てくるときにダブっていない判定(FALSE)になる。

duplicated(test)

[1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE

 

test[!duplicated(test)] # ビックリマークでT/Fをひっくり返す
  1   4   7 
"A" "B" "C" 

 

# データフレームでもやってみる。

# データフレーム作成

df <- data.frame(
  id = c(1, 2, 3, 4, 5, 4, 3, 2, 1),
  value = c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
  score = c(1, 2, 3, 1, 2, 3, 1, 2, 3)
)

df

 

# 先ほどのduplicated関数を使って、value列が被っているものを除去する。

df[!duplicated(df$value),]

 

# data.frameの場合、重複判定の対象になる情報が複数あるので、それらのダブりっぷりを加味して取り出す必要がある。ちょっとめんどくさい。例えば、idとvalueを使ってそれらが一致しているものをはじくと、以下のような感じ。

df[!(duplicated(df$id) & duplicated(df$value)),]

 

# dplyrパッケージのdistinct関数を使うと、もうちょっと書きやすい。distnct関数でいろいろやってみる。

# valueの重複を削除してみる。そのままだと、value以外の列がどっか行く。

df %>%
  dplyr::distinct(value)

# 引数.keep_allにTRUEを与えると、他の列も残る。

df %>%
  dplyr::distinct(value, .keep_all = TRUE)

 

# 複数列を対象にdistinct関数を実行する場合、引数に列名をつらつらと与えれば良い。

df %>%
  dplyr::distinct(id, value, .keep_all = TRUE)

 

# 例えば、重複している場合は中央値を代表値としてとってきたい、ということがあるとする。その場合、重複上の削除というよりも、グループごとの集計のニュアンスが強くなる。

# そのため、dplyrパッケージのgroup_byやsummarizeを使う。

df %>% 
  dplyr::group_by(value) %>% 
  dplyr::summarise(score = median(score))

 

# 複数条件でgroup_byするなら以下のような感じ。ungroupすることで、group化を解除できる。そのあとただのdata.frameとして何かに利用するならやっとく。

df %>% 
  dplyr::group_by(id, value) %>% 
  dplyr::summarise(score = median(score)) %>% 
  ungroup()

 

おわり

 

 

【R】ggplot2でdata.frameからdotplot風のグラフを描きたい

・お題:ggplot2でdata.frameからclusterprofilerのdotplot風のグラフを描きたい。

 

# データフレームを作成
df <-
  data.frame(
    names = c("Taro", "Jiro", "Saburo", "Shiro", "Goro"),
    ages = c(25, 30, 22, 35, 28),
    weights = c(68, 55, 60, 75, 50),
    heights = c(170, 160, 165, 180, 155),
    score = c(3,5,2,4,1)
    )

df

 

# 並べたい順に並べ替え

df <-
  df %>% 
  dplyr::arrange(weights)

df

 

# 氏名をfactorに変換
df$names <- factor(df$names, levels = df$names)

 

# 描画

p <-
  df %>% 
  ggplot(aes(x = heights, y = names))

 

p +
  geom_point(aes(size = ages, color = weights), alpha = 0.7) +
  scale_color_gradient(low = "blue", high = "red") + # 色を指定
  scale_size_continuous(range = c(5, 10)) + # 大きさの幅を指定
  labs(title = "test_plot",
       x = "Height (cm)",
       y = "Name",
       size = "Age",
       color = "Weight (kg)") +
  theme_light() # テーマを寄せる

 

 

おわり

 

 

【R】grepでベクトルから要素を取り出したい

・お題:grepでベクトルから要素を取り出したい。

 

# 適当にベクトル作る。

test <- c("A1", "B1", "C2", "D2")

 

# 1で終わるのを釣ってくる。

grep(x = test, pattern = "*1")

[1] 1 2

 

test[grep(x = test, pattern = "*1")]

[1] "A1" "B1"

 

# 1で終わらないのを釣ってくる。

grep(x = test, pattern = "*1", invert = TRUE)

[1] 3 4

 

test[grep(x = test, pattern = "*1", invert = TRUE)]

[1] "C2" "D2"

 

# indexじゃなくて要素そのものを返す。

grep(x = test, pattern = "*1", value = TRUE)

[1] "A1" "B1"

 

# 大文字と小文字を区別したりしなかったり

grep(x = test, pattern = "a", ignore.case = FALSE)

integer(0)


grep(x = test, pattern = "A", ignore.case = FALSE)

[1] 1

 

grep(x = test, pattern = "a", ignore.case = TRUE)

[1] 1

 

他にもオプションいろいろあるみたいだけれど、私が使うのはこのあたり。

 

おわり