#r #data.table #conditional-statements
#r #data.table #условные операторы
Вопрос:
У меня есть набор данных следующим образом:
DT <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22), Household = c(1, 1,
1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13, 13,
13), Main = c(1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1,
1, 0, 1, 0, 1, 0), Variable = c(0.298830253959918, 0.696637114803799,
0.222731978341587, 0.641245156419456, 0.145562076370066, 0.191365477844148,
0.881263670583021, 0.314050677064662, 0.0770074657918196, 0.299236771626852,
0.872886923047494, 0.289628283880055, 0.270138675264831, 0.910147226969786,
0.582434831286225, 0.791627720726525, 0.852872802843926, 0.599723929185799,
0.558087460306338, 0.862531226564633, 0.361200983684113, 0.765999001124532
)), row.names = c(NA, -22L), class = c("tbl_df", "tbl", "data.frame"
))
К этому набору данных я хочу добавить дополнительный столбец. Если их более двух ID
Household
, я хочу Variable
, чтобы значения Household
членов, которые Main==0
суммировались и добавлялись в качестве новой переменной, добавлялись к строкам Household
членов, у которых есть Main==1
, И НАОБОРОТ. Если другого Household
элемента нет, значение равно 0
. Я бы предпочел сделать это в data.table
, но я довольно быстро застреваю. Я начал следующим образом:
# create a var with the nr of hh members
DTattempt <- setDT(DT)[, count:= .N, by=Household]
# if there is only 1 hh member, the value of New_Var = 0
DTattempt <- setDT(DTattempt)[count == 1, New_Var:= 0, by=Household]
# Now I try to fill in the value for the other rows, but here I get stuck
# I do not know how to tell R that it should only sum the other variables
DTattempt <- setDT(DTattempt)[count > 1, New_Var:= ifelse(Main==1, sum(Variable, by=Household), sum(Variable, by=Household), by=Household]
Желаемый результат:
DTnew <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22), Household = c(1, 1,
1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 12, 13, 13,
13), Main = c(1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1,
1, 0, 1, 0, 1, 0), Variable = c(0.29883025, 0.69663711, 0.22273198,
0.64124516, 0.14556208, 0.19136548, 0.88126367, 0.31405068, 0.07700747,
0.29923677, 0.87288692, 0.28962828, 0.27013868, 0.91014723, 0.58243483,
0.79162772, 0.8528728, 0.59972393, 0.55808746, 0.86253123, 0.36120098,
0.765999), New_Var = c(0.91936909, 0.29883025, 0.29883025, 0.14556208,
0.64124516, 0.88126367, 0.19136548, 0.07700747, 0.31405068, 0,
0, 0, 0.91014723, 0.27013868, 0, 0, 0, 0.55808746, 0.59972393,
0.36120098, 1.62853023, 0.36120098)), row.names = c(NA, -22L), class = c("tbl_df",
"tbl", "data.frame"))
Ответ №1:
Следующее работает:
setDT(DT)
DT[, nm := .N, by = .(Household, Main)]
[, newVar := sum(Variable), by = .(Household, Main)]
[, New_Var := sum(newVar/nm) - newVar, by = .(Household)]
[, c("nm", "newVar") := list(NULL,NULL)]
ID Household Main Variable New_Var
1: 1 1 1 0.29883025 0.91936909
2: 2 1 0 0.69663711 0.29883025
3: 3 1 0 0.22273198 0.29883025
4: 4 2 0 0.64124516 0.14556208
5: 5 2 1 0.14556208 0.64124516
6: 6 3 1 0.19136548 0.88126367
7: 7 3 0 0.88126367 0.19136548
8: 8 4 1 0.31405068 0.07700747
9: 9 4 0 0.07700747 0.31405068
10: 10 5 0 0.29923677 0.00000000
11: 11 6 1 0.87288692 0.00000000
12: 12 7 1 0.28962828 0.00000000
13: 13 8 1 0.27013868 0.91014723
14: 14 8 0 0.91014723 0.27013868
15: 15 9 1 0.58243483 0.00000000
16: 16 10 1 0.79162772 0.00000000
17: 17 11 1 0.85287280 0.00000000
18: 18 12 0 0.59972393 0.55808746
19: 19 12 1 0.55808746 0.59972393
20: 20 13 0 0.86253123 0.36120098
21: 21 13 1 0.36120098 1.62853023
22: 22 13 0 0.76599900 0.36120098
Комментарии:
1. Большое вам спасибо! Очень классный способ решить эту проблему с помощью этой третьей строки.
2. Действительно, фантастический способ!
Ответ №2:
Я знаю, что мое решение может быть не идеальным, но оно должно работать
library(tidyverse)
DT2 <- DT %>% arrange(Household, Main) %>%
mutate(new = ifelse(Main == 0, as.complex(0 1i), 1)) %>%
group_by(Household) %>%
mutate(new = sum(new*Variable)) %>%
group_by(Household, Main) %>%
mutate(new = ifelse(Main == 1, Im(new), Re(new))) %>%
ungroup() %>% arrange(ID)
Комментарии:
1. Большое вам спасибо! Принял другой ответ за то, что он немного менее сложный и является решением data.table. Один небольшой комментарий для строки ответа 10 должен быть равен нулю (потому что в домохозяйстве есть только один член).
2. О! В этом случае это проще. Я отредактирую ответ. Спасибо, что указали.
3. Для обмена значениями я использовал комплексные числа, которые можно рассматривать как двумерные числа