我正在使用一个数据集,其中对给定国家/地区的答案编码方式存在错误。让我们调用我的第一个变量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
答案 0 :(得分:0)
我会假设态度是一个因素。在这种情况下,我们可以做到
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]]] )
})
答案 1 :(得分:0)
好的,谢谢大家,我根据你的答案自己找到解决方案。我用较少的变量创建了my.data的子集,这次内部函数工作没有错误。只有它的r2evans&#39;效果最佳的脚本,如下所示
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" })
欢呼并感谢您的时间和帮助!
答案 2 :(得分:0)
OP提到了
有问题的表格中有很多国家我在这个例子中省略了。
如果要更新大表并且只有几行要更新,我建议使用data.table
仅通过引用更新,而不复制整个数据对象。
有两种方法:一种是选择和替换,另一种是使用更新连接和查找表。
这类似于OP's own answer,但采用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
的匹配行:
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][]
结果与上面显示的相同
为了测试上述解决方案,我从my.data
的给定输出中重建了table(...)
。请注意,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