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。如果您以(即长格式)而不是宽格式保存数据,则不需要循环,只需要简单的年份/姓名/字母计数聚合。