1

国勢調査線が 8 つある ( L1:L8)。現在、いくつかの記録は、国勢調査されたときNAよりもむしろ0持っています。対応するエフォート列 ( ) の値が 0 より大きい場合 (つまり、国勢調査されていることを意味します) 、各列 ( ) のすべてNAをに置き換えたいと思います。0L1:L8EFFORT_L1:EFFORT_L8

サンプルデータ:

df <-structure(list(KARTA = c("02C2H", "02C2H", "02C2H", "02C2H", 
"02C2H", "02C2H"), YEAR = c(1997L, 1997L, 1997L, 1997L, 1997L, 
1997L), ART = c("009", "031", "012", "057", "065", "073"), L1 = c(NA, 
NA, NA, NA, 2, NA), L2 = c(NA, NA, 7, NA, 3, NA), L3 = c(NA, 
NA, NA, NA, 1, NA), L4 = c(NA, NA, NA, NA, 1, NA), L5 = c(NA, 
NA, NA, NA, 1, NA), L6 = c(NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_), L7 = c(NA, NA, NA, 1, NA, 1), L8 = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), EFFORT_L1 = c(10, 
10, 10, 10, 10, 10), EFFORT_L2 = c(10, 10, 10, 10, 10, 10), EFFORT_L3 = c(9.625, 
9.625, 9.625, 9.625, 9.625, 9.625), EFFORT_L4 = c(10, 10, 10, 
10, 10, 10), EFFORT_L5 = c(9.125, 9.125, 9.125, 9.125, 9.125, 
9.125), EFFORT_L6 = c(9.75, 9.75, 9.75, 9.75, 9.75, 9.75), EFFORT_L7 = c(9.75, 
9.75, 9.75, 9.75, 9.75, 9.75), EFFORT_L8 = c(10, 10, 10, 10, 
10, 10), Total_Route_Effort = c(78.25, 78.25, 78.25, 78.25, 78.25, 
78.25)), .Names = c("KARTA", "YEAR", "ART", "L1", "L2", "L3", 
"L4", "L5", "L6", "L7", "L8", "EFFORT_L1", "EFFORT_L2", "EFFORT_L3", 
"EFFORT_L4", "EFFORT_L5", "EFFORT_L6", "EFFORT_L7", "EFFORT_L8", 
"Total_Route_Effort"), row.names = c(NA, 6L), class = "data.frame")

1 つの列のサンプル コード (8 つの列すべてに対して効率的なソリューションを探していることに注意してください):

df[is.na(df[,"L1"]) & df[,"EFFORT_L1"] > 0, "L1"] <- 0
4

3 に答える 3

4
df[paste0("L", 1:8)][is.na(df[paste0("L", 1:8)]) 
                     & df[paste0("EFFORT_L", 1:8)] > 0] <- 0

結果:

> df
  KARTA YEAR ART L1 L2 L3 L4 L5 L6 L7 L8 EFFORT_L1 EFFORT_L2
1 02C2H 1997 009  0  0  0  0  0  0  0  0        10        10
2 02C2H 1997 031  0  0  0  0  0  0  0  0        10        10
3 02C2H 1997 012  0  7  0  0  0  0  0  0        10        10
4 02C2H 1997 057  0  0  0  0  0  0  1  0        10        10
5 02C2H 1997 065  2  3  1  1  1  0  0  0        10        10
6 02C2H 1997 073  0  0  0  0  0  0  1  0        10        10
  EFFORT_L3 EFFORT_L4 EFFORT_L5 EFFORT_L6 EFFORT_L7 EFFORT_L8
1     9.625        10     9.125      9.75      9.75        10
2     9.625        10     9.125      9.75      9.75        10
3     9.625        10     9.125      9.75      9.75        10
4     9.625        10     9.125      9.75      9.75        10
5     9.625        10     9.125      9.75      9.75        10
6     9.625        10     9.125      9.75      9.75        10
  Total_Route_Effort
1              78.25
2              78.25
3              78.25
4              78.25
5              78.25
6              78.25
于 2013-03-21T09:55:08.220 に答える
3

これはあなたの質問に正確に答えるわけではありませんが、将来の問題に役立つ可能性があります。今日から両方の質問を見て、データをセミロング形式に変換して代わりに使用することを検討しましたか?

これがおもちゃの例です:

サンプルデータ

set.seed(1)
myDF <- data.frame(
  ID1 = sample(letters[1:5], 5, replace = TRUE),
  ID2 = 1:5, ID3 = "999",
  V1 = 99, V2 = 99, V3 = 99,
  EV1 = sample(0:5, 5, replace = TRUE),
  EV2 = sample(0:3, 5, replace = TRUE),
  EV3 = sample(0:2, 5, replace = TRUE),
  stringsAsFactors = FALSE
)
myDF$ID3[c(1, 4)] <- 100
myDF$V1[c(4, 5)] <- 100
myDF$V2[c(1, 3, 5)] <- 100
myDF
#   ID1 ID2 ID3  V1  V2 V3 EV1 EV2 EV3
# 1   b   1 100  99 100 99   5   0   1
# 2   b   2 999  99  99 99   5   0   2
# 3   c   3 999  99 100 99   3   2   2
# 4   e   4 100 100  99 99   3   1   1
# 5   b   5 999 100 100 99   0   3   2

セミロング(または視点によってはセミワイド)形式のデータ

myDFLong <- reshape(myDF, direction = "long", idvar = 1:3,
                    varying = 4:ncol(myDF), sep = "")
myDFLong
#           ID1 ID2 ID3 time   V EV
# b.1.100.1   b   1 100    1  99  5
# b.2.999.1   b   2 999    1  99  5
# c.3.999.1   c   3 999    1  99  3
# e.4.100.1   e   4 100    1 100  3
# b.5.999.1   b   5 999    1 100  0
# b.1.100.2   b   1 100    2 100  0
# b.2.999.2   b   2 999    2  99  0
# c.3.999.2   c   3 999    2 100  2
# e.4.100.2   e   4 100    2  99  1
# b.5.999.2   b   5 999    2 100  3
# b.1.100.3   b   1 100    3  99  1
# b.2.999.3   b   2 999    3  99  2
# c.3.999.3   c   3 999    3  99  2
# e.4.100.3   e   4 100    3  99  1
# b.5.999.3   b   5 999    3  99  2

これで、「L」列に相当する列が1つと、「EFFORT_L」列に相当する列が1つだけあることに注意してください。「時間」変数が作成されました(1〜8の「国勢調査行」に相当)。

今日から両方の質問に答える

ifelse今日からこれまでの両方の質問は、いくつかの簡単なステートメントで簡単に対処できます。

# Your first question from today
myDFLong$V <- with(myDFLong, ifelse(ID3 == 999 & V == 99, NA, V))
# Continuation from that point
myDFLong$V <- with(myDFLong, ifelse(EV > 0 & is.na(V), 0, V))
myDFLong
#           ID1 ID2 ID3 time   V EV
# b.1.100.1   b   1 100    1  99  5
# b.2.999.1   b   2 999    1   0  5
# c.3.999.1   c   3 999    1   0  3
# e.4.100.1   e   4 100    1 100  3
# b.5.999.1   b   5 999    1 100  0
# b.1.100.2   b   1 100    2 100  0
# b.2.999.2   b   2 999    2  NA  0
# c.3.999.2   c   3 999    2 100  2
# e.4.100.2   e   4 100    2  99  1
# b.5.999.2   b   5 999    2 100  3
# b.1.100.3   b   1 100    3  99  1
# b.2.999.3   b   2 999    3   0  2
# c.3.999.3   c   3 999    3   0  2
# e.4.100.3   e   4 100    3  99  1
# b.5.999.3   b   5 999    3   0  2

最終段階:必要に応じてワイドフォーマットに戻る

ベースRを使用してワイドフォーマットに再変換できますが、この場合、次のように「reshape2」パッケージを使用する方がはるかに簡単です。

library(reshape2)
myDF2 <- melt(myDFLong, id.vars=1:4)
myDFFinal <- dcast(myDF2, ID1 + ID2 + ID3 ~ variable + time)
myDFFinal
#   ID1 ID2 ID3 V_1 V_2 V_3 EV_1 EV_2 EV_3
# 1   b   1 100  99 100  99    5    0    1
# 2   b   2 999   0  NA   0    5    0    2
# 3   b   5 999 100 100   0    0    3    2
# 4   c   3 999   0 100   0    3    2    2
# 5   e   4 100 100  99  99    3    1    1

ただし、これは最後にのみ行うことをお勧めします。関数のプロットなど、データを最初から長い形式または半長い形式にするなど、多くのことを検討する価値があるかもしれません。あなたのデータのために。

ただし、データには現在名前付きの行があるため、注意してください。追加のID変数としてそれらを最大限に活用するには、データに列としてそれらを追加する必要があります。

于 2013-03-21T10:44:05.173 に答える
1

「L」変数の数が固定されていない場合は、これを使用できます。

l.vars <- grep("^L\\d$", names(df),value=TRUE)
for (v in l.vars) {
  effort.var <- paste0("EFFORT_", v)
  df[is.na(df[,v]) & df[,effort.var] > 0, v] <- 0
}
于 2013-03-21T09:59:47.140 に答える