#r #function #loops
#r
Вопрос:
У меня есть фрейм данных, который выглядит следующим образом:
Size count Density
1 large 12 NA
2 medium 7 NA
3 small 4 NA
4 large 68 NA
5 medium 53 NA
6 small 25 NA
7 large 139 NA
8 medium 85 NA
9 small 47 NA
10 large 148 NA
11 medium 88 NA
12 small 39 NA
Я пытаюсь вычислить столбец плотности. Итак, если размер большой, я хочу разделить количество на 225. Если размер средний, разделите количество на 144, а если размер маленький, разделите количество на 49.
Я понятия не имею, как бы я это сделал, поэтому буду признателен за любую помощь!
Ответ №1:
Мне нравится создавать справочные таблицы для подобных вещей. Я считаю, что это легко проверить и отладить:
density_lookup = data.frame(
size = c("large", "medium", "small"),
denominator = c(225, 144, 49)
)
## Inspect, make sure it looks right
density_lookup
# size denominator
# 1 large 225
# 2 medium 144
# 3 small 49
# With base R
your_data = merge(your_data, density_lookup, by = "size", all.x = TRUE)
your_data$Density = with(your_data, count / denominator)
# with dplyr
library(dplyr)
your_data %>%
left_join(density_lookup, by = "size") %>%
mutate(Density = count / denominator)
Вы также можете использовать именованные векторы или ifelse()
операторы, но мне нравится этот подход, потому что он очень хорошо обобщает — при необходимости вы можете сопоставить несколько столбцов. Вы можете сохранить поиск в файле CSV, если хотите поделиться им с пользователями, не являющимися R.
Ответ №2:
Если классы не слишком большие, вы можете использовать ifelse()
, хотя решение @GregorThomas более практично:
#Base R
df$Density <- ifelse(df$Size=='large',df$count/225,
ifelse(df$Size=='medium',df$count/144,df$count/49))
Вывод:
Size count Density
1 large 12 0.05333333
2 medium 7 0.04861111
3 small 4 0.08163265
4 large 68 0.30222222
5 medium 53 0.36805556
6 small 25 0.51020408
7 large 139 0.61777778
8 medium 85 0.59027778
9 small 47 0.95918367
10 large 148 0.65777778
11 medium 88 0.61111111
12 small 39 0.79591837
Некоторые используемые данные:
#Data
df <- structure(list(Size = c("large", "medium", "small", "large",
"medium", "small", "large", "medium", "small", "large", "medium",
"small"), count = c(12L, 7L, 4L, 68L, 53L, 25L, 139L, 85L, 47L,
148L, 88L, 39L), Density = c(0.0533333333333333, 0.0486111111111111,
0.0816326530612245, 0.302222222222222, 0.368055555555556, 0.510204081632653,
0.617777777777778, 0.590277777777778, 0.959183673469388, 0.657777777777778,
0.611111111111111, 0.795918367346939)), row.names = c("1", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "11", "12"), class = "data.frame")
Ответ №3:
Это тоже работает
within(df1, Density <- count / c("large" = 225, "medium" = 144, "small" = 49)[Size])
Вывод
# A tibble: 12 x 3
Size count Density
<chr> <dbl> <dbl>
1 large 12 0.0533
2 medium 7 0.0486
3 small 4 0.0816
4 large 68 0.302
5 medium 53 0.368
6 small 25 0.510
7 large 139 0.618
8 medium 85 0.590
9 small 47 0.959
10 large 148 0.658
11 medium 88 0.611
12 small 39 0.796