[英]Recode the value of a variable given the value of another one
我正在使用一個數據集,其中給定國家/地區的答案的編碼方式存在錯誤。 讓我們將第一個變量my.data$country_year
,將第二個變量my.data$country_year
my.data$attitude
。 兩者的表提供以下輸出:
table(my.data$country_year, my.data$attitude)
(1) Very Suitable (2) Suitable (3) Somewhat Suitable (4) Not Suitable
Yemen.2006 101 142 1192 0
Lebanon.2007 13 14 60 1063
Yemen.2007 49 113 122 248
Palestine.2008 131 653 387 2093
有問題的表格有很多國家/地區在本示例中省略了我想要做的是讓R在原始數據集中執行以下操作,同時保留所有其他國家/地區的觀測值:
for my.data $ country =“ Yemen.2006”&my.data $ attitude =“(3)有點適合”,“(4)不適合。
for my.data $ country =“ Yemen.2006”和my.data $ attitude =“(2)合適”,“(3)有點合適”
換句話說,我想將2006年在也門進行的調查的態度變量的第二和第三值移至右側,而無需創建新變量。 我希望結果如下
(1) Very Suitable (2) Suitable (3) Somewhat Suitable (4) Not Suitable
Yemen.2006 101 0 142 1192
Lebanon.2007 13 14 60 1063
Yemen.2007 49 113 122 248
Palestine.2008 131 653 387 2093
我將假設態度是一個因素。 在這種情況下,我們可以
levels(my.data$attitude) <- levels(my.data$attitude)[c(1, 4, 2, 3)]
如果還沒有成為一個因素,只需(至少暫時)使其成為一個因素即可:
my.data$attitude <- factor(my.data$attitude)
levels(my.data$attitude) <- levels(my.data$attitude)[c(1, 4, 2, 3)]
my.data$attitude <- as.character(my.data$attitude)
僅 Yemen.2006
更新。 Yemen.2006
再次假設態度是一個因素:
new_value_index <- c(1, 4, 2, 3)
my.data <- within(my.data, {
attitude[country == "Yemen.2006"] <- levels(attitude)[new_value_index[attitude[country == "Yemen.2006]]] )
})
好的,謝謝大家,我根據您的回答來尋找解決方案。 我使用較少的變量創建了my.data的子集,這一次內部函數正常工作而沒有錯誤。 最好的是r2evans的腳本,如下所示
my.data2 <- within(my.data2, {attitude[country_year=="Yemen.2006" &
attitude=="(3) Somewhat Suitable"] <- "(4) Not Suitable At All" })
my.data2 <- within(my.data2, {attitude[country_year=="Yemen.2006" &
attitude=="(2) Suitable"] <- "(3) Somewhat Suitable" })
干杯,感謝您的寶貴時間和幫助!
OP提到
有問題的表格有很多國家/地區,在此示例中我省略了。
如果表很大,只有幾行要更新,我建議使用data.table
,它僅通過引用受影響的行來更新,而不復制整個數據對象。
有兩種方法:一種是選擇和替換 ,另一種是使用帶有查找表的更新聯接。
這類似於OP自己的答案,但是在data.table
語法中:
library(data.table)
setDT(my.data)[country_year == "Yemen.2006" & attitude == "(3) Somewhat Suitable",
attitude := "(4) Not Suitable"]
my.data[country_year == "Yemen.2006" & attitude == "(2) Suitable",
attitude := "(3) Somewhat Suitable"]
請注意, my.data
是在原位修改的 ,因此沒有必要將結果分配給另一個數據框。 可以通過以下任一方法驗證結果
dcast(my.data, country_year ~ attitude)
要么
table(my.data$country_year, my.data$attitude)
(1) Very Suitable (2) Suitable (3) Somewhat Suitable (4) Not Suitable Yemen.2006 101 0 142 1192 Lebanon.2007 13 14 60 1063 Yemen.2007 49 113 122 248 Palestine.2008 131 653 387 2093
在這里,將預先創建一個lookup
表,然后將其用於my.data
僅更新my.data
的匹配行:
library(data.table)
lookup <- data.table(
country_year = "Yemen.2006",
attitude.old = c("(2) Suitable", "(3) Somewhat Suitable"),
attitude.new = c("(3) Somewhat Suitable", "(4) Not Suitable"))
setDT(my.data)[lookup, on = .(country_year, attitude == attitude.old),
attitude := attitude.new][]
結果與上面顯示的相同
為了測試上述解決方案,我從table(...)
的給定輸出中重構了my.data
。 請注意, my.data
是長格式,需要melt()
示例表並根據計數給行復制多次:
DT_wide <- fread(
"country_year, (1) Very Suitable, (2) Suitable, (3) Somewhat Suitable, (4) Not Suitable
Yemen.2006, 101, 142, 1192, 0
Lebanon.2007, 13, 14 , 60, 1063
Yemen.2007 , 49, 113, 122, 248
Palestine.2008, 131, 653, 387, 2093")
DT_wide[, country_year := forcats::fct_inorder(country_year)]
my.data <- melt(DT_wide, id = "country_year", variable.name = "attitude")[
rep(1:.N, value)][, value := NULL][]
my.data
country_year attitude 1: Yemen.2006 (1) Very Suitable 2: Yemen.2006 (1) Very Suitable 3: Yemen.2006 (1) Very Suitable 4: Yemen.2006 (1) Very Suitable 5: Yemen.2006 (1) Very Suitable --- 6377: Palestine.2008 (4) Not Suitable 6378: Palestine.2008 (4) Not Suitable 6379: Palestine.2008 (4) Not Suitable 6380: Palestine.2008 (4) Not Suitable 6381: Palestine.2008 (4) Not Suitable
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.