簡體   English   中英

R-比較具有不同值的數據框的不同列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM