R 尝试循环数据帧并将值附加到列表中,但对于循环不';行不通
下面简要介绍一下我的数据R 尝试循环数据帧并将值附加到列表中,但对于循环不';行不通,r,list,dataframe,loops,R,List,Dataframe,Loops,下面简要介绍一下我的数据 X name sex X1880 X1881 1 1 Mary F 7065 6919 2 2 Anna F 2604 2698 3 3 Emma F 2003 2034 4 4 Elizabeth F 1939 1852 5 5 Minnie F 1746 1653 每个“X---”代表一年(截至2010年),列“name”代表一个孩子的唯一名字,因此任何名字和年份之间的对应数
X name sex X1880 X1881
1 1 Mary F 7065 6919
2 2 Anna F 2604 2698
3 3 Emma F 2003 2034
4 4 Elizabeth F 1939 1852
5 5 Minnie F 1746 1653
每个“X---”代表一年(截至2010年),列“name”代表一个孩子的唯一名字,因此任何名字和年份之间的对应数字是在“X---”年出生的孩子的数量,并指定了名字(例如,1880年出生的7065只玛丽)
我想在涵盖1931年到2010年的专栏中循环,找出那一年出生的儿童总数,然后找出那一年出生的名字以字母表中每个字母开头的儿童总数。最后,我想得到每年出生的名字以每个字母开头的儿童的百分比,并将其存储到一个列表中,这样我就可以在同一个图表上绘制所有字母/所有年份的趋势线
这是我的密码
allnames <- read.csv("SSA-longtail-names.csv")
girls <- subset(allnames, allnames$sex=="F")
year_columns <- as.vector(names(girls)[54:134])
percs <- list()
years <- length(year_columns)
letters <- length(LETTERS)
for (i in range(1:years)){
total = sum(girls[year_columns[i]])
for (n in range(1:letters)){
l <- toString(LETTERS[n])
sub <- girls[(grep(l, girls$name)),year_columns[i]]
sub_total <- sum(sub[year_columns[i]])
percent <- (sub_total / total) * 100
percs <- append(percs, percent)
}
}
allnames这里有一种方法,使用dplyr
、tidyr
和stringr
通过旋转年份列来创建一个长数据表
library(dplyr)
library(tidyr)
library(stringr)
data2 <- data %>%
pivot_longer(cols = c(-X, -name, -sex), names_to = "year", values_to = "births") %>%
complete.cases() %>% # remove NA rows
mutate(year = as.integer(str_remove(year, "X")),
first_letter = str_sub(name, start = 1, end = 1) %>%
filter(year >= 1931 & year <= 2010)
现在可以进行一些打印,例如使用ggplot2
library(ggplot2)
# this only looks at the English vowels to make a manageable example
ggplot(data = data3 %>% filter(first_letter %in% c("A", "E", "I", "O", "U"),
aes(x = year, y = total, color = first_letter)) +
geom_line()
下面是一种使用dplyr
、tidyr
和stringr
通过旋转年份列来生成长数据表的方法
library(dplyr)
library(tidyr)
library(stringr)
data2 <- data %>%
pivot_longer(cols = c(-X, -name, -sex), names_to = "year", values_to = "births") %>%
complete.cases() %>% # remove NA rows
mutate(year = as.integer(str_remove(year, "X")),
first_letter = str_sub(name, start = 1, end = 1) %>%
filter(year >= 1931 & year <= 2010)
现在可以进行一些打印,例如使用ggplot2
library(ggplot2)
# this only looks at the English vowels to make a manageable example
ggplot(data = data3 %>% filter(first_letter %in% c("A", "E", "I", "O", "U"),
aes(x = year, y = total, color = first_letter)) +
geom_line()
我已将解决方案分为您描述的三个部分。如果您只关注百分比,则可以忽略第一部分(总计),并合并第二部分和第三部分:
library(dplyr)
library(stringr)
library(tidyr)
data <- tibble(name = c('Mary', 'Anna', 'Emma', 'Elizabeth', 'Minnie'),
sex = rep('F', 5),
X1880 = c(7065, 2604, 2003, 1939, 1746),
X1881 = c(6919, 2698, 2034, 1852, 1653))
total <- data %>%
summarise(across(X1880:X1881, sum)) %>%
pivot_longer(everything(), names_to = 'year', values_to = 'total')
total
# year total
# <chr> <dbl>
# 1 X1880 15357
# 2 X1881 15156
totalPerLetter <- data %>%
mutate(letter = str_extract(name, '^.')) %>%
select(letter, starts_with('X')) %>%
pivot_longer(-letter, names_to = 'year', values_to = 'count') %>%
group_by(letter, year) %>%
mutate(count = sum(count)) %>%
distinct()
totalPerLetter
# letter year count
# <chr> <chr> <dbl>
# 1 M X1880 8811
# 2 M X1881 8572
# 3 A X1880 2604
# 4 A X1881 2698
# 5 E X1880 3942
# 6 E X1881 3886
pctPerLetter <- totalPerLetter %>%
group_by(year) %>%
mutate(total = sum(count)) %>%
ungroup() %>%
mutate(percent = count/(total/100))
pctPerLetter
# letter year count total percent
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 M X1880 8811 15357 57.4
# 2 M X1881 8572 15156 56.6
# 3 A X1880 2604 15357 17.0
# 4 A X1881 2698 15156 17.8
# 5 E X1880 3942 15357 25.7
# 6 E X1881 3886 15156 25.6
库(dplyr)
图书馆(stringr)
图书馆(tidyr)
数据%
pivot_更长(everything(),name_to='year',value_to='total')
全部的
#全年总数
#
#1 X1880 15357
#2 X1881 15156
每封信总计%
变异(字母=str_extract(名称,'^.'))%>%
选择(字母,以('X')开头)%>%
pivot_longer(-letter,names_to='year',values_to='count')%>%
分组单位(字母,年份)%>%
突变(计数=总和(计数))%>%
不同的()
全字母
#信年数
#
#1米X1880 8811
#2米X1881 8572
#3 A X1880 2604
#4 A X1881 2698
#5 E X1880 3942
#6 E X1881 3886
pctPerLetter%
组别(年份)%>%
突变(总数=总和(计数))%>%
解组()%>%
变异(百分比=计数/(总数/100))
pctPerLetter
#信年总数百分比
#
#1米X1880 8811 15357.4
#2米X1881 8572 15156.6
#3 A X1880 2604 15357 17.0
#4 A X1881 2698 15156 17.8
#5 E X1880 3942 15357 25.7
#6 E X1881 3886 15156 25.6
我已将解决方案分为您描述的三个部分。如果您只关注百分比,则可以忽略第一部分(总计),并合并第二部分和第三部分:
library(dplyr)
library(stringr)
library(tidyr)
data <- tibble(name = c('Mary', 'Anna', 'Emma', 'Elizabeth', 'Minnie'),
sex = rep('F', 5),
X1880 = c(7065, 2604, 2003, 1939, 1746),
X1881 = c(6919, 2698, 2034, 1852, 1653))
total <- data %>%
summarise(across(X1880:X1881, sum)) %>%
pivot_longer(everything(), names_to = 'year', values_to = 'total')
total
# year total
# <chr> <dbl>
# 1 X1880 15357
# 2 X1881 15156
totalPerLetter <- data %>%
mutate(letter = str_extract(name, '^.')) %>%
select(letter, starts_with('X')) %>%
pivot_longer(-letter, names_to = 'year', values_to = 'count') %>%
group_by(letter, year) %>%
mutate(count = sum(count)) %>%
distinct()
totalPerLetter
# letter year count
# <chr> <chr> <dbl>
# 1 M X1880 8811
# 2 M X1881 8572
# 3 A X1880 2604
# 4 A X1881 2698
# 5 E X1880 3942
# 6 E X1881 3886
pctPerLetter <- totalPerLetter %>%
group_by(year) %>%
mutate(total = sum(count)) %>%
ungroup() %>%
mutate(percent = count/(total/100))
pctPerLetter
# letter year count total percent
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 M X1880 8811 15357 57.4
# 2 M X1881 8572 15156 56.6
# 3 A X1880 2604 15357 17.0
# 4 A X1881 2698 15156 17.8
# 5 E X1880 3942 15357 25.7
# 6 E X1881 3886 15156 25.6
库(dplyr)
图书馆(stringr)
图书馆(tidyr)
数据%
pivot_更长(everything(),name_to='year',value_to='total')
全部的
#全年总数
#
#1 X1880 15357
#2 X1881 15156
每封信总计%
变异(字母=str_extract(名称,'^.'))%>%
选择(字母,以('X')开头)%>%
pivot_longer(-letter,names_to='year',values_to='count')%>%
分组单位(字母,年份)%>%
突变(计数=总和(计数))%>%
不同的()
全字母
#信年数
#
#1米X1880 8811
#2米X1881 8572
#3 A X1880 2604
#4 A X1881 2698
#5 E X1880 3942
#6 E X1881 3886
pctPerLetter%
组别(年份)%>%
突变(总数=总和(计数))%>%
解组()%>%
变异(百分比=计数/(总数/100))
pctPerLetter
#信年总数百分比
#
#1米X1880 8811 15357.4
#2米X1881 8572 15156.6
#3 A X1880 2604 15357 17.0
#4 A X1881 2698 15156 17.8
#5 E X1880 3942 15357 25.7
#6 E X1881 3886 15156 25.6
< /代码> ,考虑将数据重整为长格式(用于合并、清理、聚合、建模和绘图的数据分析的更好格式)。
重塑
girls_long <- reshape(girls, varying = names(girls)[4:ncol(girls)], times = names(girls)[4:ncol(girls)],
idvar = c("X", "name", "sex"),
v.names = "count", timevar = "year", ids=NULL,
new.row.names = 1:1E5, direction = "long")
girls_long$year <- as.integer(gsub("X", "", girls_long$year))
girls_long
# X name sex year count
# 1 1 Mary FALSE 1880 7065
# 2 2 Anna FALSE 1880 2604
# 3 3 Emma FALSE 1880 2003
# 4 4 Elizabeth FALSE 1880 1939
# 5 5 Minnie FALSE 1880 1746
# 6 1 Mary FALSE 1881 6919
# 7 2 Anna FALSE 1881 2698
# 8 3 Emma FALSE 1881 2034
# 9 4 Elizabeth FALSE 1881 1852
# 10 5 Minnie FALSE 1881 1653
<代码> GracsSyLon < P >,考虑将数据重整为长格式(用于合并、清理、聚合、建模和绘图的数据分析的更好格式)。
重塑
girls_long <- reshape(girls, varying = names(girls)[4:ncol(girls)], times = names(girls)[4:ncol(girls)],
idvar = c("X", "name", "sex"),
v.names = "count", timevar = "year", ids=NULL,
new.row.names = 1:1E5, direction = "long")
girls_long$year <- as.integer(gsub("X", "", girls_long$year))
girls_long
# X name sex year count
# 1 1 Mary FALSE 1880 7065
# 2 2 Anna FALSE 1880 2604
# 3 3 Emma FALSE 1880 2003
# 4 4 Elizabeth FALSE 1880 1939
# 5 5 Minnie FALSE 1880 1746
# 6 1 Mary FALSE 1881 6919
# 7 2 Anna FALSE 1881 2698
# 8 3 Emma FALSE 1881 2034
# 9 4 Elizabeth FALSE 1881 1852
# 10 5 Minnie FALSE 1881 1653
girls\u您很久没有尝试使用NULL
而不是list()
?这应该避免在percs
中使用NAs。如果您以(即长格式)而不是宽格式保存数据,则不需要循环,只需要简单的年份/姓名/字母计数聚合。您是否尝试使用NULL
而不是list()
?这应该避免在percs
中使用NAs。如果您以(即长格式)而不是宽格式保存数据,则不需要循环,只需要简单的年份/姓名/字母计数聚合。