1

更新(以下の最初の質問)

@akrun@ulfelderのおかげで、最初の例は 1 年しかなかったので、十分に複雑ではないことに気付きました。数年にわたるデータは、より現実的であり、他の人にとってより役立つ場合があります。

代わりに、私のデータは、

df <- structure(list(yr_month = structure(1:7, .Label = c("2014-1", "2014-2", 
"2014-3", "2015-4", "2016-4", "2016-6", "2017-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yrQ", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")
df
#      yrQ    a    b
# 1 2014-1 4.14 4.25
# 2 2014-2 2.83 3.50
# 3 2014-3 3.71 3.50
# 4 2015-4 4.15 3.50
# 5 2016-4 4.63 3.50
# 6 2016-6 4.91 3.50
# 7 2017-7 5.31 5.00

そして、2014 年 3 月以前、2014-3、2014-3 と 2016-4 の間、および 2016-4 以降をカバーするカテゴリを作成したいと考えました。このようなものを手に入れるために、

#   yr.cat    yrQ    a    b
# 1    "A" 2014-1 4.14 4.25
# 2    "A" 2014-2 2.83 3.50
# 3    "B" 2014-3 3.71 3.50
# 4    "B" 2015-4 4.15 3.50
# 5    "B" 2016-4 4.63 3.50
# 6    "C" 2016-6 4.91 3.50
# 7    "C" 2017-7 5.31 5.00

最初の質問

このようなデータセットがあるとします。

df <- structure(list(yr_month = structure(1:7, .Label = c("2016-1", "2016-2", 
"2016-3", "2016-4", "2016-5", "2016-6", "2016-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yrQ", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")
df
#      yrQ    a    b
# 1 2016-1 4.14 4.25
# 2 2016-2 2.83 3.50
# 3 2016-3 3.71 3.50
# 4 2016-4 4.15 3.50
# 5 2016-5 4.63 3.50
# 6 2016-6 4.91 3.50
# 7 2016-7 5.31 5.00

これで、数値変数ifelse()を分類するために使用できます。aこのような、

df$a.cat <- ifelse(df$a < 3.8, c("tiny"), ifelse(df$a < 4.8, c("medium"), c("huge")) )
df
#      yrQ    a    b  a.cat
# 1 2016-1 4.14 4.25 medium
# 2 2016-2 2.83 3.50   tiny
# 3 2016-3 3.71 3.50   tiny
# 4 2016-4 4.15 3.50 medium
# 5 2016-5 4.63 3.50 medium
# 6 2016-6 4.91 3.50   huge
# 7 2016-7 5.31 5.00   huge

しかし、ある期間を表す変数をクレートしたい場合はどうでしょうか。2016 年 3 月より前、2016-3と の間2016-32016-5と の後2016-5。データを変換してからts、それwindow()を切り取り、元に戻すことができることはわかっていますが、 if else on を使用してこのようなものに到達するためのよりスマートな方法はありませんyrQか?

たどり着きたいのはこういうことなのですが、

  yr.cat    yrQ    a    b
1    "A" 2016-1 4.14 4.25
2    "A" 2016-2 2.83 3.50
3    "B" 2016-3 3.71 3.50
4    "B" 2016-4 4.15 3.50
5    "B" 2016-5 4.63 3.50
6    "C" 2016-6 4.91 3.50
7    "C" 2016-7 5.31 5.00
4

2 に答える 2

1

質問で提供された入力データは、データ構造内の同じ列yrQyr_month異なるポイントを参照していて、一貫性がないようです。代わりにこの入力を想定しましたが、これは、 に示されているのと同じ名前で一貫性を保つために で (年/月ではなく年/四半期を示唆しています)を に置き換えyrQたことを除いて同じです。.Namesyr_monthlist()

df <- structure(list(yr_month = structure(1:7, .Label = c("2014-1", "2014-2", 
"2014-3", "2015-4", "2016-4", "2016-6", "2017-7"), class = "factor"), 
    a = c(4.14, 2.83, 3.71, 4.15, 4.63, 4.91, 5.31), b = c(4.25, 
    3.5, 3.5, 3.5, 3.5, 3.5, 5)), .Names = c("yr_month", "a", "b"
), row.names = c(NA, 7L), class = "data.frame")

質問の例のデータには 1 桁の月しかありませんが、1 桁 (1 月、2 月、...、9 月) と 2 桁 (10 月、11 月、12 月) の月が混在している場合でも機能する必要があると想定しています。

1)クラスに変換し"yearmon"(これは、この列で他のことを行う必要がある場合にも役立つ場合があります)、各カット ポイントとの比較を実行し、それらを追加して、それぞれ前、間、後を表す数値 0、1、または 2 を与えます。次に、1 を追加し、それをカテゴリ名のベクトルの添字として使用します (ここではLETTERS)。これは、比較用語を追加するだけで、より多くのカテゴリに拡張できます。

library(zoo)

df$yr_month <- as.yearmon(df$yr_month) ##
transform(df, yr.cat = LETTERS[ (yr_month >= "2014-03") + (yr_month > "2016-04") + 1])

与える:

  yr_month    a    b yr.cat
1 Jan 2014 4.14 4.25      A
2 Feb 2014 2.83 3.50      A
3 Mar 2014 3.71 3.50      B
4 Apr 2015 4.15 3.50      B
5 Apr 2016 4.63 3.50      B
6 Jun 2016 4.91 3.50      C
7 Jul 2017 5.31 5.00      C

2) パッケージなしで実行するには、(1) で ## とマークされた行を以下のコード行に変更します。ここでは、クラスに変換yr_monthしてから"Date"、その文字表現の日の部分を削除します。これにより、月が 2 桁になるため、1 桁と 2 桁の月の比較が適切に機能します。((1)"yearmon"クラスでは自動的に処理されます。)

df$yr_month <- sub("...$", "", as.Date(paste0(df$yr_month, -1)))

改訂いくつかの改訂を行いました。

于 2016-12-03T12:58:15.177 に答える
1

cut「yrQ」から月の部分文字列を抽出した後に使用できます

df$yr.cat <- cut(as.numeric(sub(".*-", "", df$yrQ)), 
               breaks = c(-Inf,2, 5, Inf), labels = LETTERS[1:3])
df$yr.cat
#[1] A A B B B C C
#Levels: A B C

更新された例に基づいて

cut(as.numeric(sub("-", ".", df$yrQ)),
       breaks = c(-Inf, 2014.2, 2016.5, Inf), labels = LETTERS[1:3])
#[1] A A B B B C C
#Levels: A B C
于 2016-12-03T10:26:51.110 に答える