#r #dataframe #assign
#r #фрейм данных #присвоить
Вопрос:
Я ищу более эффективный способ выполнения очень простой задачи: добавление нового столбца со значениями, указанными для существующих строк. Образец фрейма данных (называемый ess) имеет страны и (обзор) раунд. Я хочу добавить столбец «dem» со значениями из внешнего источника. Вот фрагмент:
id cntry essround dem
1 AL 1
2 AT 1
3 BE 1
4 BG 1
5 HR 1
6 AL 2
7 AT 2
8 BE 2
9 BG 2
10 HR 2
«Длинный» способ сделать это заключается в следующем:
ess$dem <- NA
ess$dem[ess$cntry=="AL" amp; ess$essround==1] <- 3.5
ess$dem[ess$cntry=="AT" amp; ess$essround==1] <- 1
ess$dem[ess$cntry=="BE" amp; ess$essround==1] <- 1.5
ess$dem[ess$cntry=="BG" amp; ess$essround==1] <- 2
ess$dem[ess$cntry=="HR" amp; ess$essround==1] <- 2
ess$dem[ess$cntry=="AL" amp; ess$essround==2] <- 3
ess$dem[ess$cntry=="AT" amp; ess$essround==2] <- 1
ess$dem[ess$cntry=="BE" amp; ess$essround==2] <- 1
ess$dem[ess$cntry=="BG" amp; ess$essround==2] <- 1.5
ess$dem[ess$cntry=="HR" amp; ess$essround==2] <- 2
Проблема в том, что этот способ выполнения становится очень длинным, когда у меня 36 стран и 6 раундов — таким образом, у меня получается 216 строк кода. (Становится хуже, когда я хочу создать несколько новых столбцов в одном и том же режиме …)
Нет ли способа сжать подобную операцию?? Можно ли это сделать в одной строке, где код зависит от «позиции» в соответствующих списках значений?
Комментарии:
1. Вы ищете
ess$dem <- c(3.5, 1, 1.5, 2, 2, 3, 1, 1, 1.5, 2)
?2. хорошо, можете ли вы дать нам какой-нибудь пример df для работы? как
dem
выглядит ограничение df?
Ответ №1:
tidyverse
Сначала вам нужно создать data.frame, который будет содержать значения: ie ess$dem[ess$cntry=="AL" amp; ess$essround==1] <- 3.5
должен стать строкой в conds
data.frame:
## expand grid to create all possible combinations of cntry and essround
conds <- expand.grid(cntry=c("AL","AT","BE","BG","HR"), essround=1:2) %>% mutate(dem = c(3.5,1,1.5,2,2,3,1,1,1.5,2))
## first row will be "AL" 1 3.5 which is the first condition
conds
cntry essround dem
1 AL 1 3.5
2 AT 1 1.0
3 BE 1 1.5
4 BG 1 2.0
5 HR 1 2.0
6 AL 2 3.0
7 AT 2 1.0
8 BE 2 1.0
9 BG 2 1.5
10 HR 2 2.0
ess %>% left_join(conds)
Joining, by = c("cntry", "essround")
cntry essround dem
1 AT 1 1.0
2 AT 2 1.0
3 HR 2 2.0
4 BG 2 1.5
5 HR 2 2.0
6 HR 1 2.0
7 BG 2 1.5
8 BG 1 2.0
9 HR 2 2.0
10 BG 1 2.0
11 AT 1 1.0
12 BG 2 1.5
13 AL 1 3.5
14 HR 1 2.0
15 BE 2 1.0
16 AL 2 3.0
17 AL 1 3.5
18 AL 1 3.5
19 AT 1 1.0
20 AT 1 1.0
Комментарии:
1. Спасибо — это работает. Left_join — теперь я понял. Я настроил второй фрейм данных (содержащий «условия») в Excel — это достаточно просто и лучше, чем иметь сотни строк кода…
2. @dbartram также по умолчанию будут назначены строки, у которых нет условия соответствия
NA
Ответ №2:
Создание фиктивных данных:
ess = data.frame(
contry = sample(c("AL","AT","BE","BG","HR","AL","AT","BE","BG","HR"), 20, TRUE),
essround = sample(1:2, 20, TRUE))
Теперь код:
ess$dem <- NA
values = c(3.5,1,1.5,2,2,3,1,1,1.5,2)
groups = unique(ess$contry)
for(i in 1:length(groups)){
ess[ess$contry==groups[i],"dem"] <- values[i]
}
Вывод:
contry essround dem
1 BE 1 3.5
2 HR 2 1.0
3 AT 2 1.5
4 BG 1 2.0
5 AT 1 1.5
6 AT 2 1.5
7 AT 2 1.5
8 AT 2 1.5
9 BG 2 2.0
10 BE 2 3.5
11 AT 1 1.5
12 AT 2 1.5
13 BE 1 3.5
14 AT 2 1.5
15 HR 1 1.0
16 BG 1 2.0
17 BE 1 3.5
18 BG 1 2.0
19 AT 2 1.5
20 AT 2 1.5