3

サンプル データフレームの使用:

df <- structure(list(KY27SCH1 = c(4, 4, 4, 4, NA, 5, 2, 4, 4, NA, 4, 
                                  5, 3, 5, 5), KY27SCH2 = c(5, 4, 4, 4, NA, 4, 1, 4, 4, NA, 4, 
                                                            5, 4, 5, 5), KY27SCH3 = c(4, 4, 5, 4, NA, 4, 4, 4, 5, NA, 5, 
                                                                                      5, 3, 5, 5), KY27SCH4 = c(3, 5, 5, 4, NA, 5, 4, 5, 5, NA, 5, 
                                                                                                                5, 4, 5, 5)), .Names = c("KY27SCH1", "KY27SCH2", "KY27SCH3", 
                                                                                                                                         "KY27SCH4"), row.names = 197:211, class = "data.frame")

この新しい列を元のデータフレームにバインドする前に、1 行のコードを適用して 4 つの異なる列を一緒に追加します。

KC27sc_R <- rowSums(df[, c("KY27SCH1", "KY27SCH2", "KY27SCH3", "KY27SCH4")], na.rm = TRUE)
df <- cbind(df, KC27sc_R) # Adds columns to survey dataframe

次に、以下に詳述する結果の表を使用して、変数 KC27sc_R を再コーディングします。

5= -4.287
6 = -3.040
7 = -2.405
8 = -1.960
9 = -1.605
10 = -1.296
11 = -1.011
12 = -0.735
13 = -0.456
14 = -0.168
15 = 0.134
16 = 0.454
17 = 0.796
18 = 1.166
19 = 1.574
20 = 2.035
21 = 2.582
22 = 3.299 
23 = 4.594

つまり、列 KC27sc_R の 5 は -4.287 になります。

各数値を順番に処理することなく、数値のリストから列を再コーディングする方法はありますか? 私は通常、再コード化機能を使用しますが、大きなリストでこれを行う方法がわかりません。

どんな助けでも大歓迎です。

4

7 に答える 7

7

ルックアップ テーブルdata.frameを次のようなとして配置したとします。

mydf <- structure(list(V1 = c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
    16, 17, 18, 19, 20, 21, 22, 23), V2 = c(-4.287, -3.04, -2.405, 
    -1.96, -1.605, -1.296, -1.011, -0.735, -0.456, -0.168, 0.134, 
    0.454, 0.796, 1.166, 1.574, 2.035, 2.582, 3.299, 4.594)), .Names = c("V1", 
    "V2"), class = "data.frame", row.names = c(NA, -19L))
mydf
#    V1     V2
# 1   5 -4.287
# 2   6 -3.040
# 3   7 -2.405
# 4   8 -1.960
# 5   9 -1.605
# 6  10 -1.296
# 7  11 -1.011
# 8  12 -0.735
# 9  13 -0.456
# 10 14 -0.168
# 11 15  0.134
# 12 16  0.454
# 13 17  0.796
# 14 18  1.166
# 15 19  1.574
# 16 20  2.035
# 17 21  2.582
# 18 22  3.299
# 19 23  4.594

次のようなものを使用して、探しているものを取得できるはずです。

df$RECODED <- mydf$V2[match(as.character(df$KC27sc_R), as.character(mydf$V1))]
df
#     KY27SCH1 KY27SCH2 KY27SCH3 KY27SCH4 KC27sc_R RECODED
# 197        4        5        4        3       16   0.454
# 198        4        4        4        5       17   0.796
# 199        4        4        5        5       18   1.166
# 200        4        4        4        4       16   0.454
# 201       NA       NA       NA       NA        0      NA
# 202        5        4        4        5       18   1.166
# 203        2        1        4        4       11  -1.011
# 204        4        4        4        5       17   0.796
# 205        4        4        5        5       18   1.166
# 206       NA       NA       NA       NA        0      NA
# 207        4        4        5        5       18   1.166
# 208        5        5        5        5       20   2.035
# 209        3        4        3        4       14  -0.168
# 210        5        5        5        5       20   2.035
# 211        5        5        5        5       20   2.035

そこas.characterにある部分は、潜在的な FP 問題を軽減するのに役立ちます。


これは、提供されているソリューションと概念的に非常に似mergeていますが、はるかに高速になる可能性があります。

人工データセットのベンチマーク:

set.seed(1)
df <- data.frame(matrix(sample(0:25, 100000, replace = TRUE), ncol = 2))

library(microbenchmark)
microbenchmark(
  A = {
    df2 <- merge(df, mydf, by.x="X1", by.y="V1", sort = FALSE)
  },
  B = {
    df3 <- cbind(df, recoded = mydf$V2[match(as.character(df$X1), 
                                             as.character(mydf$V1))])
  }
)
Unit: milliseconds
#  expr       min        lq    median       uq       max neval
#     A 141.32530 149.61354 154.99230 162.7845 239.26242   100
#     B  24.93267  25.32541  25.73723  26.0792  96.44209   100

基本的なマッチング アプローチは、 の 5 倍以上の速さmergeです。さらに、merge行の順序付けでファンキーなことをする傾向があります。df元のデータセットの最初の数行 ( )、結合されたデータセット ( ) df2、および私のソリューション ( )の最初の数行を比較しdf3ます。ご覧のとおり、" " を指定したにもかかわらず、mergeは完全に再配置されています。data.framesort = FALSE

head(df)
#   X1 X2
# 1  6 15
# 2  9 18
# 3 14  8
# 4 23  3
# 5  5 22
# 6 23  1
head(df2)
#   X1 X2    V2
# 1  6 15 -3.04
# 2  6 23 -3.04
# 3  6  3 -3.04
# 4  6  0 -3.04
# 5  6 20 -3.04
# 6  6 16 -3.04
head(df3)
#   X1 X2 recoded
# 1  6 15  -3.040
# 2  9 18  -1.605
# 3 14  8  -0.168
# 4 23  3   4.594
# 5  5 22  -4.287
# 6 23  1   4.594
于 2013-08-27T17:19:27.737 に答える
1

まず、結果のテーブルがマトリックスに格納されているとしますyo

yo <- matrix(0, nrow = 19, ncol = 2)
yo[, 1] <- c(5:23)
yo[, 2] <- c( -4.287, -3.040, -2.405, -1.960, -1.605, -1.296, -1.011, -0.735, -0.456, -0.168, 0.134, 0.454, 0.796, 1.166, 1.574, 2.035, 2.582, 3.299, 4.594)

つまり、 の最初の列はyo変更したい値に対応し、2 番目の列は変更対象の値に対応します。簡単に言えば、yo関数として扱います。最初の列はこの関数のx変数で、2 番目の列は関数の出力です。

最初に把握する必要があるのは、KC27sc_R の値のインデックスが実際に存在するyo[, 1]ことです (この行では、実際に古い値を新しい値に置き換えることができます)。これは次のように行われます。

ind <- which( df$KC27sc_R %in% yo[,1] )

ind変更可能な KC27sc_R のすべての値の行が表示されます。次のステップは、これらすべての値を取得することです。

a <- df[ind,]$KC27sc_R

最後のステップは、値aをそれらの値とリンクすることですyo[, 1]-文字通りyo[, 1]、対応する各値を見つけることができる場所の行を見つけますa-関数matchはここで役立ちます:

b <- match( a, yo[,1] )

同様indに、bはインデックスです。 の各値について、 のこの値の置換を見つけるために のどaの行に移動する必要があるかを示します。最後のステップは、あなたの値を置き換えることです:yo[, 2]adf

df[ind, "KC27sc_R"] <- yo[b, 2]

それはトリックを行います。

于 2013-09-01T01:58:09.273 に答える
1

私はあなたの質問が正しかったと100%確信しているわけではありません. しかし、あなたが求めているのは、整数から値へのマッピングがあり、データ フレーム (またはベクトル) 内のすべての整数をマッピングで指定された値に置き換えたいということだと思います。

マッピングをリストに入れます:

code = list()
code[[5 ]] = -4.287
code[[6 ]] = -3.040
code[[7 ]] = -2.405
code[[8 ]] = -1.960
code[[9 ]] = -1.605
code[[10]] = -1.296
code[[11]] = -1.011
code[[12]] = -0.735
code[[13]] = -0.456
code[[14]] = -0.168
code[[15]] = 0.134
code[[16]] = 0.454
code[[17]] = 0.796
code[[18]] = 1.166
code[[19]] = 1.574
code[[20]] = 2.035
code[[21]] = 2.582
code[[22]] = 3.299 
code[[23]] = 4.594

次に、apply (または vector の場合は sapply) を使用して置換を行います。

apply(df, c(1,2), function(x) code[[x]])
于 2013-08-27T13:29:41.897 に答える
1

最小限の入力を必要とし、移植可能な回答:

# Your original values
origval = seq(5,23)
newval = c(-4.287, -3.04, -2.405, -1.96, -1.605, -1.296, -1.011, -0.735, -0.456, -0.168, 0.134, 0.454, 0.796, 1.166, 1.574, 2.035, 2.582, 3.299, 4.594)

# generate a relationship
sp = smooth.spline(origval,newval)

# look up a value based on your original sequence
pval = predict(sp, origval)

pval$y予測された (変換された) ポイントが含まれるようになりました。

データ系列にない値 (5.5 など) であっても、任意の順序で、predict関数の代わりに他の値のセットを入れることができます。origval

データセットに適用すると、変数のプレースホルダーを作成して、その値を「予測」できます。

df$KY_Rnew = df$KC27sc_R
df$KY_Rnew[!is.na(df$KY_Rnew)] = predict(sp,df$KY_Rnew[!is.na(df$KY_Rnew)])$y
于 2013-08-27T20:40:23.210 に答える
1

マッピング値がすべて整数であると仮定すると、マッピング値の位置にコード化された値を含むベクトルを作成できます。

# using mydf defined by Ananda Mahto:
mydf <- structure(list(V1 = c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
 16, 17, 18, 19, 20, 21, 22, 23), V2 = c(-4.287, -3.04, -2.405, 
 -1.96, -1.605, -1.296, -1.011, -0.735, -0.456, -0.168, 0.134, 
 0.454, 0.796, 1.166, 1.574, 2.035, 2.582, 3.299, 4.594)), .Names = c("V1", 
 "V2"), class = "data.frame", row.names = c(NA, -19L))

# create vector with index positions corresponding to objective values:
vmap <- rep(NA, length=max(mydf$V1)) 
vmap[mydf$V1] <- mydf$V2

vmap
# [1]     NA     NA     NA     NA -4.287 -3.040 -2.405 -1.960 -1.605 -1.296
# [11] -1.011 -0.735 -0.456 -0.168  0.134  0.454  0.796  1.166  1.574  2.035
# [21]  2.582  3.299  4.594

# Assign NA to zero values in KC27sc_R (as you cannot have a zero position in a R vector)
# (this could also be another value defined in mydf if you want zero to map to something)
KC27sc_R[KC27sc_R==0] <- NA

# Then, select the values in vmap using the indices defined in KC27sc_R:
Krecode <- vmap[KC27sc_R]
data.frame(KC27sc_R, Krecode)


# KC27sc_R Krecode
# 197       16   0.454
# 198       17   0.796
# 199       18   1.166
# 200       16   0.454
# 201       NA      NA
# 202       18   1.166
# ... etc

すべての操作がベクトル化されるため、これは長いリストでかなり高速になるはずです。

于 2013-08-27T23:22:33.047 に答える