![](/img/trans.png)
[英]R- format a data.frame into another 'combined' data.frame based on common values within a column dependent across different columns
[英]R- compare different columns of a data frame with different values
我目前正在使用一項名為 SHARE 的調查研究微數據。 我想使用一個變量進行教育,但它的編碼方式有點困難。
在調查中,家庭被問及他們擁有什么學位。 每個學位有一個列,如果被采訪者有學位或沒有學位,則取值為 0 或 1。 問題是我有兩個不同程度的國家,但他們使用的是同一列,所以我必須去用戶手冊找到每個國家的度數分別對應於 0 或 1。我能夠這樣做並且然后將其轉化為衡量教育的國際方式。
我的想法是對每一列求和,然后每個家庭只有一列。 但是,我無法繼續,因為有些人有很多學位。 我想得到每個家庭的最高學位。 我想在這個問題上得到你的幫助。
以下是我擁有的和想要的表格:
讓我們想象一下,德國的第一個文憑相當於國際標准的第一個文憑,德國的第二個和第三個相當於國際標准的第二個文憑,德國的最后一個文憑與國際標准的第三個相同。 在法國,我們有 first = first int., second = second int.,third = third int.。 也沒有第四個文憑。 然后我有一張桌子:
country= c( "Germany", "Germany", "Germany", "France" , "France", "France")
degree_one= c( 1, 1, 1, 1 , 1, 1)
degree_two = c( 0, 1, 0, 1 , 1, 0)
degree_three= c( 1, 0, 1, 1 , 1, 0)
degree_four = c( 1, 0, 0, NA ,NA, NA)
f = data.frame(country,degree_one,degree_two,degree_three,degree_four)
然后我可以翻譯並嘗試通過對所有內容求和來創建我的可變學位:
f$degree_one = ifelse(f$country == "Germany" & f$degree_one == 1,1,f$degree_one)
f$degree_two = ifelse(f$country == "Germany" & f$degree_two == 1,2,f$degree_two)
f$degree_three = ifelse(f$country == "Germany" & f$degree_three == 1,2,f$degree_three)
f$degree_four = ifelse(f$country == "Germany" & f$degree_four == 1,3,f$degree_four)
f$degree_one = ifelse(f$country == "France" & f$degree_one == 1,1,f$degree_one)
f$degree_two = ifelse(f$country == "France" & f$degree_two == 1,2,f$degree_two)
f$degree_three = ifelse(f$country == "France" & f$degree_three == 1,3,f$degree_three)
f$degree_four = ifelse(f$country == "France" & f$degree_four == "NA",0,f$degree_four)
f = replace(f, is.na(f), 0)
f2 = f %>% mutate(degree = degree_one + degree_two + degree_three + degree_four )
不幸的是,它不起作用,我想要的應該是這樣的:
degree = c(3,2,2,3,3,1)
f3 = data.frame(f,degree)
我試圖用一個while循環來做某事,但它沒有用,因為有人知道我該如何解決我的問題嗎? 我試圖讓它盡可能清楚,我希望你能理解,並且有人對如何解決這個問題提出一個想法。
謝謝 :)
這是一種使用data.table
的方法
library(data.table)
##
# create degree map by country
#
degreeMap <- data.table(country=c('France', 'Germany'))
degreeMap <- degreeMap[, .(degree=paste('degree', c('one', 'two', 'three', 'four'), sep='_')), by=.(country)]
degreeMap[country=='France', intlDegree:=c(1,2,3,NA)]
degreeMap[country=='Germany', intlDegree:=c(1,2,2,3)]
##
# process your data
#
setDT(f)
f[, indx:=1:.N] # need an index column to recover original order
f[, HH:=1:.N, by=.(country)] # need a HH column to distinguish different HH w/in country
maxDegree <- melt(f, id=c('country', 'HH', 'indx'), variable.name='degree', value.name = 'flag')
maxDegree <- maxDegree[flag > 0] # remove rows with flag=0 or NA
setorder(maxDegree, HH, degree)
maxDegree <- maxDegree[, .SD[.N], keyby=.(country, HH)]
maxDegree[degreeMap, intlDegree:=i.intlDegree, on=.(country, degree)]
setorder(maxDegree, indx)
maxDegree
## country HH indx degree flag intlDegree
## 1: Germany 1 1 degree_four 1 3
## 2: Germany 2 2 degree_two 1 2
## 3: Germany 3 3 degree_three 1 2
## 4: France 1 4 degree_three 1 3
## 5: France 2 5 degree_three 1 3
## 6: France 3 6 degree_one 1 1
因此,這會將您的f
轉換為data.table
並添加一個索引列和一個 HH 列來區分一個國家/地區的 HH。
然后我們使用melt(...)
轉換為長格式。 在長格式中,四個degree_
列被縮減為兩列:一個指示度數是否適用的flag
列,以及一個指示度數的degree
列。
然后我們刪除所有帶有 0 或 NA 標志的行,然后為每個國家和 HH 提取最后剩余的行(最高級別)。
最后,我們加入degreeMap
以獲得等效的 intlDegree。
將NA
更改為0
,然后對度數列求和:
f <- f %>%
mutate(
degree_one = ifelse(is.na(degree_one), 0, degree_one),
degree_two = ifelse(is.na(degree_two), 0, degree_two),
degree_three = ifelse(is.na(degree_three), 0, degree_three),
degree_four = ifelse(is.na(degree_four), 0, degree_four),
degree_sum = degree_one + degree_two + degree_three + degree_four
)
或者,如果你想看中dplyr
f <- f %>%
mutate(across(contains("degree"), \(x) {ifelse(is.na(x), 0, x)})) %>%
mutate(degree_sum = select(., contains("degree")) %>% rowSums())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.