我试图避免使用loop
来重新编码家庭伴侣的变量标识。
hldid
表示家庭,而persid
表示家庭中的人。
变量partner
表示伙伴的persid
,变量child
表示该行是否为子级。
两个合作伙伴的变量partner
中缺少的是persid
。
例如对于hldid == 1
,persid == 1
的{{1}}的值为0
,而应为partner
。
这是数据的样子:
2
我设法创建了一个非常丑陋的循环,但是对于整个数据集来说太慢了。
> test
hldid persid age sex relresp partner child
1 1 1 26 2 0 0 0
2 1 2 26 1 1 1 0
3 2 1 59 2 0 0 0
4 2 2 64 1 1 1 0
5 3 1 76 2 0 0 0
6 4 1 65 2 0 0 0
7 4 2 64 1 1 1 0
8 5 1 52 2 0 0 0
9 5 2 51 1 1 1 0
10 5 3 20 2 21 0 1
11 5 4 14 2 21 0 1
12 7 1 69 1 0 0 0
13 7 2 70 2 1 1 0
您知道如何使用test$partnerREC = test$partner
for(i in 1:13){
for(j in 1:13){
if(
test$hldid[i] == test$hldid[i+1] & # verify if household is the same
(test$persid[i] == test$partner[j])
)
{
test$partnerREC[i] = test$persid[j] # put the persid for each partner
}
}
}
> test
hldid persid age sex relresp partner child partnerREC
1 1 1 26 2 0 0 0 2
2 1 2 26 1 1 1 0 1
3 2 1 59 2 0 0 0 2
4 2 2 64 1 1 1 0 1
5 3 1 76 2 0 0 0 0
6 4 1 65 2 0 0 0 2
7 4 2 64 1 1 1 0 1
8 5 1 52 2 0 0 0 2
9 5 2 51 1 1 1 0 1
10 5 3 20 2 21 0 1 0
11 5 4 14 2 21 0 1 0
12 7 1 69 1 0 0 0 2
13 7 2 70 2 1 1 0 1
解决此问题吗?
data.table
答案 0 :(得分:4)
可能的解决方案:
library(data.table) # load the package
setDT(test) # convert 'test' to a 'data.table'
test[, partnerREC := persid[c(pmin(2,.N):1,rep(0,(pmax(.N,2)-2)))] *
(persid %in% 1:2) *
(.N != 1)
, by = hldid][]
给出:
> test hldid persid age sex relresp partner child partnerREC 1: 1 1 26 2 0 0 0 2 2: 1 2 26 1 1 1 0 1 3: 2 1 59 2 0 0 0 2 4: 2 2 64 1 1 1 0 1 5: 3 1 76 2 0 0 0 0 6: 4 1 65 2 0 0 0 2 7: 4 2 64 1 1 1 0 1 8: 5 1 52 2 0 0 0 2 9: 5 2 51 1 1 1 0 1 10: 5 3 20 2 21 0 1 0 11: 5 4 14 2 21 0 1 0 12: 7 1 69 1 0 0 0 2 13: 7 2 70 2 1 1 0 1
此解决方案基于以下假设(从示例数据中得出):只有“ perid” 1和2是伙伴,更高的是孩子。
这是什么:
hldid
分组persid[c(pmin(2,.N):1,rep(0,(pmax(.N,2)-2)))]
,其中pmin
用于确保当一个家庭只有一个人时构造长度为1的向量。(persid %in% 1:2)
可获得儿童的动物园动物。(.N != 1)
乘以一个人的家庭的零值。答案 1 :(得分:1)
df <- data.frame(matrix(data = NA, ncol = 7))
names(df) <- names(test)
for(id in unique(test$hldid)){
t <- test[test$hldid==id,]
t$partner[t$persid == t$partner[t$partner!=0]] <- t$persid[which(t$partner!=0)]
df <- rbind(df, t)
}
df <- df[-1,]
答案 2 :(得分:1)
基本的R解决方案比Jaap的data.table
solution更复杂。
我正在处理副本。
test2 <- test
运行问题代码后,运行以下代码。
test2$partnerREC <- test2$partner
sp <- split(test2, test2$hldid)
test2 <- lapply(sp, function(DF){
i <- with(DF, which(persid %in% partner))
j <- with(DF, which(partner %in% persid))
#cat("i:", i, "\tj:", j, "\n")
DF$partnerREC[i] <- DF$persid[j]
DF
})
test2 <- do.call(rbind, test2)
row.names(test2) <- NULL
现在比较两个结果。
identical(test, test2)
#[1] TRUE
答案 3 :(得分:0)
您可以通过一些dplyr
步骤到达那里,以结合自身的数据并在persid == partner
时更新partner的值。
test2 <- left_join(test, test %>% select(hldid, persid, partner) %>% filter(partner != 0), by=c("hldid")) %>%
filter(persid.x == partner.y) %>%
mutate(partner.x = persid.y)
这将使您的户主的伴侣ID匹配,但是您必须将其重新加入原始数据(我不确定dplyr lingo中的SQL update
等同)。< / p>
答案 4 :(得分:0)
library(tidyverse)
test <- tribble(
~hldid, ~persid, ~age, ~sex, ~relresp, ~partner, ~child,
1, 1, 26, 2, 0, 0, 0,
1, 2, 26, 1, 1, 1, 0,
2, 1, 59, 2, 0, 0, 0,
2, 2, 64, 1, 1, 1, 0,
3, 1, 76, 2, 0, 0, 0,
4, 1, 65, 2, 0, 0, 0,
4, 2, 64, 1, 1, 1, 0,
5, 1, 52, 2, 0, 0, 0,
5, 2, 51, 1, 1, 1, 0,
5, 3, 20, 2, 21, 0, 1,
5, 4, 14, 2, 21, 0, 1,
7, 1, 69, 1, 0, 0, 0,
7, 2, 70, 2, 1, 1, 0)
test %>%
# arrange the data in case the raw data did not
arrange(hldid, child, persid) %>%
# group each household
group_by(hldid) %>%
# match first and second household person as each other's partner
mutate(partnerREC = ifelse(persid == first(persid), nth(persid, 2), first(persid))) %>%
# correct partnerREC for child and single
mutate(partnerREC = ifelse(child == 1 | is.na(partnerREC), 0, partnerREC))
# un-group it
ungroup()
答案 5 :(得分:0)
使用$val = "sgadjgjsd".($array['c'] ?? '');
的{{1}}解决方案
使用loop
脚本
rcpp
并运行功能
rcpp
第一种情况(如果您知道如何解决)只有一点点问题