给定另一个变量的值重新编码一个变量的值
Recode the value of a variable given the value of another one
我使用的数据集在给定国家/地区的答案编码方式上存在错误。让我们调用我的第一个变量 my.data$country_year
和第二个变量 my.data$attitude
。两者中的 table 给出以下输出:
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
有问题的 table 有很多我在这个 example.What 中省略的国家 我想做的是让 R 在我的原始数据集中执行以下操作,同时保留所有的观察结果其他国家:
for my.data$country="Yemen.2006" & my.data$attitude="(3) 有点随table", "(4) 不随table.
for my.data$country="Yemen.2006" & my.data$attitude="(2) Suitable", "(3) Something Suitable
换句话说,我想将 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
同样,假设态度是一个因素:
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 的一个子集,这次 within 函数工作正常。只有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 提到
The table in question has a lot of countries which I omitted in this example.
如果 table 很大并且只有几行要更新,我建议使用 data.table
,它仅通过引用 更新受影响的行 无需复制整个数据对象。
有两种方法:一种是 select 和替换,另一种是使用 update join 和查找table.
Select 并替换
这类似于 但在 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
table,然后在连接中使用它来仅更新 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()
样本 table 并根据计数给定的次数复制行:
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
我使用的数据集在给定国家/地区的答案编码方式上存在错误。让我们调用我的第一个变量 my.data$country_year
和第二个变量 my.data$attitude
。两者中的 table 给出以下输出:
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
有问题的 table 有很多我在这个 example.What 中省略的国家 我想做的是让 R 在我的原始数据集中执行以下操作,同时保留所有的观察结果其他国家:
for my.data$country="Yemen.2006" & my.data$attitude="(3) 有点随table", "(4) 不随table.
for my.data$country="Yemen.2006" & my.data$attitude="(2) Suitable", "(3) Something Suitable
换句话说,我想将 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
同样,假设态度是一个因素:
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 的一个子集,这次 within 函数工作正常。只有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 提到
The table in question has a lot of countries which I omitted in this example.
如果 table 很大并且只有几行要更新,我建议使用 data.table
,它仅通过引用 更新受影响的行 无需复制整个数据对象。
有两种方法:一种是 select 和替换,另一种是使用 update join 和查找table.
Select 并替换
这类似于 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
table,然后在连接中使用它来仅更新 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()
样本 table 并根据计数给定的次数复制行:
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